Dynamics CRM 2016 SDK 新機能: メタデータ Web API その 2: フィールド

みなさん、こんにちは。

前回に引き続き、Dynamics CRM 2016 SDK の新機能として正式版と
なった Web API について紹介します。

今回は Web API メタデータサービスの機能より、フィールドのメタ
データ操作を紹介します。

概要

既存の組織サービス同様、Web API を利用してメタデータを操作する
ことが可能です。サポートされる操作は多岐に渡りますが、今回は
フィールドの操作を紹介します。

フィールドの作成

まずカスタムフィールドを作成します。

プログラムの実装

1. 前回利用した Visual Studio ソリューションを開き、Program.cs
ファイルを開きます。新しく以下のメソッドを追加します。

public async Task RunFieldMetadata(string accessToken)
{
    // HttpClient の作成
    using (HttpClient httpClient = new HttpClient())
    {
        //  Web API アドレスの作成
        string serviceUrl = serverUrl + "/api/data/v8.0/";
        // ヘッダーの設定
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

    }
}

2. Main メソッドの以下のコードを書き換えて、新しいメソッドを
呼ぶように変更します。

元)  
Task.WaitAll(Task.Run(async () => await app.RunEntityMetadata(result.AccessToken)));

変更後)
Task.WaitAll(Task.Run(async () => await app.RunFieldMetadata(result.AccessToken)));

3. 新しく追加した RunFieldMetadata メソッド内に以下のコードを追加して、
カスタムフィールドを作成するエンティティを取得します。今回は取引先企業に
カスタムフィールドを作成してみます。

// 取引先企業エンティティの取得
HttpResponseMessage entityRes = await httpClient.GetAsync(serviceUrl + "EntityDefinitions?$select=MetadataId&$filter=LogicalName eq 'account'");
JToken entity = JObject.Parse(entityRes.Content.ReadAsStringAsync().Result)["value"][0];

4. 以下のコードを追加して、カスタムフィールドの情報を作成します。

// カスタムフィールドの情報を作成
string customFieldMeta = @"
{    
    '@odata.type': '#Microsoft.Dynamics.CRM.StringAttributeMetadata',
    'Format': 'Text',
    'FormatName': { 'Value': 'Text' },
    'ImeMode': 'Auto',
    'MaxLength': 100,
    'AttributeType': 'String',
    'DisplayName': {
        'LocalizedLabels': [{
            'Label': 'サンプルテキスト列',
            'LanguageCode': 1041
        }],
        'UserLocalizedLabel': {
            'Label': 'サンプルテキスト列',
            'LanguageCode': 1041
        }
    },
    'RequiredLevel': { 'Value': 'ApplicationRequired' },
    'SchemaName': 'new_textfield'
}";

5. 以下のコードを追加して作成要求を送信します。

// カスタムフィールドの作成
HttpResponseMessage createRes = await httpClient.PostAsync(serviceUrl + "EntityDefinitions(" + entity["MetadataId"] + ")/Attributes",
    new StringContent(customFieldMeta, Encoding.UTF8, "application/json"));

動作確認

1. F5 キーを押下してプログラムを実行します。

2. 認証ダイアログが表示されたらログインします。

image

3. プログラム完了後、カスタムフィールドが作成されて
いることを確認します。

image

フィールドの取得

メタデータサービスも OData を利用したクエリが可能です。次の作業に
あたり上記で追加したカスタムフィールドの作成要求はコメントアウト
しておきます。

プログラムの実装

1. 上記のコードに続いて以下のコードを追加します。フィールドの
論理名を利用してフィルターします。

// 作成したフィールドの取得
HttpResponseMessage fieldRes = await httpClient.GetAsync(serviceUrl + "EntityDefinitions(" + entity["MetadataId"] + ")/Attributes?$filter=LogicalName eq 'new_textfield'");
JToken field = JObject.Parse(fieldRes.Content.ReadAsStringAsync().Result)["value"][0];

2. 以下のコードを追加して結果を表示します。フィールドのメタ
データは内容が多いため、今回はそのまますべて表示しました。

// 詳細を表示
Console.WriteLine(field);

動作確認

1. F5 キーを押下してプログラムを実行します。

2. 認証ダイアログが表示されたらログインします。

3. フィールドの詳細が表示されます。

image

フィールドの削除

更新および削除も通常のレコード同様に行えます。ここでは削除の
方法を紹介します。

プログラムの実装

上記のコードに続いて以下のコードを追加します。レコードの ID に
相当するものとして、MetadataId があります。これを取得した内容から
取り出して、指定しています。

// 作成したフィールドの削除
HttpResponseMessage deleteRes = await httpClient.DeleteAsync(serviceUrl + "EntityDefinitions(" + entity["MetadataId"] + ")/Attributes(" + field["MetadataId"] + ")");

動作確認

1. F5 キーを押下してプログラムを実行します。

2. 認証ダイアログが表示されたらログインします。

3. 作成したフィールドが削除されることを確認します。

以下に今回追加したメソッドを示します。

public async Task RunFieldMetadata(string accessToken)
{
    // HttpClient の作成
    using (HttpClient httpClient = new HttpClient())
    {
        //  Web API アドレスの作成
        string serviceUrl = serverUrl + "/api/data/v8.0/";
        // ヘッダーの設定
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

        // 取引先企業エンティティの取得
        HttpResponseMessage entityRes = await httpClient.GetAsync(serviceUrl + "EntityDefinitions?$select=MetadataId&$filter=LogicalName eq 'account'");
        JToken entity = JObject.Parse(entityRes.Content.ReadAsStringAsync().Result)["value"][0];

        // カスタムフィールドの定義作成
        string customFieldMeta = @"
        {    
            '@odata.type': '#Microsoft.Dynamics.CRM.StringAttributeMetadata',
            'Format': 'Text',
            'FormatName': { 'Value': 'Text' },
            'ImeMode': 'Auto',
            'MaxLength': 100,
            'AttributeType': 'String',
            'DisplayName': {
                'LocalizedLabels': [{
                    'Label': 'サンプルテキスト列',
                    'LanguageCode': 1041
                }],
                'UserLocalizedLabel': {
                    'Label': 'サンプルテキスト列',
                    'LanguageCode': 1041
                }
            },
            'RequiredLevel': { 'Value': 'ApplicationRequired' },
            'SchemaName': 'new_textfield'
        }";

        // カスタムフィールドの作成
        HttpResponseMessage createRes = await httpClient.PostAsync(serviceUrl + "EntityDefinitions(" + entity["MetadataId"] + ")/Attributes",
            new StringContent(customFieldMeta, Encoding.UTF8, "application/json"));

        Console.WriteLine("Press Enter to continue");
        Console.ReadLine();

        // 作成したフィールドの取得
        HttpResponseMessage fieldRes = await httpClient.GetAsync(serviceUrl + "EntityDefinitions(" + entity["MetadataId"] + ")/Attributes?$filter=LogicalName eq 'new_textfield'");
        JToken field = JObject.Parse(fieldRes.Content.ReadAsStringAsync().Result)["value"][0];

        // 詳細を表示
        Console.WriteLine(field);
        Console.WriteLine("Press Enter to continue");
        Console.ReadLine();

        // 作成したフィールドの削除
        HttpResponseMessage deleteRes = await httpClient.DeleteAsync(serviceUrl + "EntityDefinitions(" + entity["MetadataId"] + ")/Attributes(" + field["MetadataId"] + ")");
    }
}

まとめ

エンティティ同様にフィールドのメタデータ操作ができます。
次回は関連について紹介します。お楽しみに!

- 中村 憲一郎

※本情報の内容(添付文書、リンク先などを含む)は、作成日時点でのものであり、予告なく変更される場合があります