目次
Dataverse の WebAPI を C# で叩く系記事たちの目次です。
今回の本文
前回の続きです。
これまでデータ取得、テーブルに列追加、行追加をしてきましたが、今回は列追加その2です。
API で取得した列定義 JSON をもとに列を追加してみます。。
■ 動かし方
コマンドライン引数で、WebAPIのエンドポイントを入れます。Web の GUI で 「テーブル 定義への API リンク」をした時の URL です。
■ 概要
- 事前にテーブルの列定義の JSON を取得し、一列分の定義部分だけ用意しておく
- その定義から
MetadataId、CreatedOn、ModifiedOnを削除 LogicalName、SchemaName、Labelを新たに追加する列名に変更- Post。
簡単ですね。
実際はもっと様々な方の型の列があり複雑でしょうが、たいていの場合、テーブルへの列追加は「ほかのテーブルに追加した列とほぼ同じ設定の列」「同テーブルの既存の列とほぼ同じ設定の列」でしょうから、この定義を取得して少し書き換えるとその JSON で列追加ができる、は何かに使えそうです。しかし要改善。
次回以降、改善してみますね。
using System.Text; string s = args[0] + "/Attributes"; string json = """ { "@odata.type": "#Microsoft.Dynamics.CRM.MemoAttributeMetadata", "HasChanged": null, "AttributeOf": null, "AttributeType": "Memo", "ColumnNumber": 37, "DeprecatedVersion": null, "IntroducedVersion": "1.0", "EntityLogicalName": "crf6f_newtable001", "IsCustomAttribute": true, "IsPrimaryId": false, "IsValidODataAttribute": true, "IsPrimaryName": false, "IsValidForCreate": true, "IsValidForRead": true, "IsValidForUpdate": true, "CanBeSecuredForRead": true, "CanBeSecuredForCreate": true, "CanBeSecuredForUpdate": true, "IsSecured": false, "IsRetrievable": false, "IsFilterable": false, "IsSearchable": false, "IsManaged": false, "LinkedAttributeId": null, "LogicalName": "crf6f_user_multiline_richtext_01_02", "IsValidForForm": true, "IsRequiredForForm": false, "IsValidForGrid": true, "SchemaName": "crf6f_user_multiline_richtext_01_02", "ExternalName": null, "IsLogical": false, "IsDataSourceSecret": false, "InheritsFrom": null, "SourceType": null, "AutoNumberFormat": null, "Format": "Text", "ImeMode": "Auto", "MaxLength": 2000, "IsLocalizable": false, "AttributeTypeName": { "Value": "MemoType" }, "Description": { "LocalizedLabels": [ { "Label": "", "LanguageCode": 1041, "IsManaged": false, "HasChanged": null } ], "UserLocalizedLabel": { "Label": "", "LanguageCode": 1041, "IsManaged": false, "HasChanged": null } }, "DisplayName": { "LocalizedLabels": [ { "Label": "new rich 02", "LanguageCode": 1041, "IsManaged": false, "HasChanged": null } ], "UserLocalizedLabel": { "Label": "new rich 02", "LanguageCode": 1041, "IsManaged": false, "HasChanged": null } }, "IsAuditEnabled": { "Value": true, "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifyauditsettings" }, "IsGlobalFilterEnabled": { "Value": false, "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifyglobalfiltersettings" }, "IsSortableEnabled": { "Value": false, "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifyissortablesettings" }, "IsCustomizable": { "Value": true, "CanBeChanged": true, "ManagedPropertyLogicalName": "iscustomizable" }, "IsRenameable": { "Value": true, "CanBeChanged": true, "ManagedPropertyLogicalName": "isrenameable" }, "IsValidForAdvancedFind": { "Value": true, "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifysearchsettings" }, "RequiredLevel": { "Value": "None", "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifyrequirementlevelsettings" }, "CanModifyAdditionalSettings": { "Value": true, "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifyadditionalsettings" }, "Settings": [], "FormatName": { "Value": "RichText" } } """; /* string json = """ { "@odata.type": "#Microsoft.Dynamics.CRM.MemoAttributeMetadata", "MetadataId": "883d1c59-a975-f011-b4cb-00224862d28c", "HasChanged": null, "AttributeOf": null, "AttributeType": "Memo", "ColumnNumber": 37, "DeprecatedVersion": null, "IntroducedVersion": "1.0", "EntityLogicalName": "crf6f_newtable001", "IsCustomAttribute": true, "IsPrimaryId": false, "IsValidODataAttribute": true, "IsPrimaryName": false, "IsValidForCreate": true, "IsValidForRead": true, "IsValidForUpdate": true, "CanBeSecuredForRead": true, "CanBeSecuredForCreate": true, "CanBeSecuredForUpdate": true, "IsSecured": false, "IsRetrievable": false, "IsFilterable": false, "IsSearchable": false, "IsManaged": false, "LinkedAttributeId": null, "LogicalName": "crf6f_user_multiline_richtext_01_02", "IsValidForForm": true, "IsRequiredForForm": false, "IsValidForGrid": true, "SchemaName": "crf6f_user_multiline_richtext_01_02", "ExternalName": null, "IsLogical": false, "IsDataSourceSecret": false, "InheritsFrom": null, "CreatedOn": "2025-08-10T05:17:59Z", "ModifiedOn": "2025-08-10T05:17:59Z", "SourceType": null, "AutoNumberFormat": null, "Format": "Text", "ImeMode": "Auto", "MaxLength": 2000, "IsLocalizable": false, "AttributeTypeName": { "Value": "MemoType" }, "Description": { "LocalizedLabels": [ { "Label": "", "LanguageCode": 1041, "IsManaged": false, "MetadataId": "c1578bc6-7d47-4a46-bb14-bed6b34f9780", "HasChanged": null } ], "UserLocalizedLabel": { "Label": "", "LanguageCode": 1041, "IsManaged": false, "MetadataId": "c1578bc6-7d47-4a46-bb14-bed6b34f9780", "HasChanged": null } }, "DisplayName": { "LocalizedLabels": [ { "Label": "\u30e6\u30fc\u30b6\u30fc\u5b9a\u7fa9\u8907\u6570\u884c\u30ea\u30c3\u30c1\u30c6\u30ad\u30b9\u30c8_02", "LanguageCode": 1041, "IsManaged": false, "MetadataId": "f6642691-599d-4598-8cb1-ea15b41d75db", "HasChanged": null } ], "UserLocalizedLabel": { "Label": "\u30e6\u30fc\u30b6\u30fc\u5b9a\u7fa9\u8907\u6570\u884c\u30ea\u30c3\u30c1\u30c6\u30ad\u30b9\u30c8_02", "LanguageCode": 1041, "IsManaged": false, "MetadataId": "f6642691-599d-4598-8cb1-ea15b41d75db", "HasChanged": null } }, "IsAuditEnabled": { "Value": true, "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifyauditsettings" }, "IsGlobalFilterEnabled": { "Value": false, "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifyglobalfiltersettings" }, "IsSortableEnabled": { "Value": false, "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifyissortablesettings" }, "IsCustomizable": { "Value": true, "CanBeChanged": true, "ManagedPropertyLogicalName": "iscustomizable" }, "IsRenameable": { "Value": true, "CanBeChanged": true, "ManagedPropertyLogicalName": "isrenameable" }, "IsValidForAdvancedFind": { "Value": true, "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifysearchsettings" }, "RequiredLevel": { "Value": "None", "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifyrequirementlevelsettings" }, "CanModifyAdditionalSettings": { "Value": true, "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifyadditionalsettings" }, "Settings": [], "FormatName": { "Value": "RichText" } } """; */ /* string json = """ { "AttributeType": "String", "AttributeTypeName": { "Value": "StringType" }, "Description": { "@odata.type": "Microsoft.Dynamics.CRM.Label", "LocalizedLabels": [ { "@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel", "Label": "Type the name of the bank", "LanguageCode": 1033 } ] }, "DisplayName": { "@odata.type": "Microsoft.Dynamics.CRM.Label", "LocalizedLabels": [ { "@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel", "Label": "Bank Name 02", "LanguageCode": 1033 } ] }, "RequiredLevel": { "Value": "None", "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifyrequirementlevelsettings" }, "SchemaName": "new_BankName_02", "@odata.type": "Microsoft.Dynamics.CRM.StringAttributeMetadata", "FormatName": { "Value": "Text" }, "MaxLength": 100 } """; */ string r = await new RkDataverseHttpClient(s).PostAsync(json); Console.WriteLine(r); class RkDataverseHttpClient { public string Resource { get; init; } public Uri BaseAddress { get; init; } public string Path { get; init; } public static string ClientId { get; } = "51f81489-12ee-4a9e-aaae-a2591f45987d"; public static string RedirectUri { get; } = "http://localhost"; Microsoft.Identity.Client.AuthenticationResult Token { get; set; } HttpClient HttpClient { get; init; } public RkDataverseHttpClient(string resource) { var uri = new Uri(resource); Resource = uri.Scheme + "://" + uri.Host; BaseAddress = new Uri(Resource + "/api/data/v9.2/"); Path = new string(resource.Skip(BaseAddress.AbsoluteUri.Length).ToArray()); Authentication().GetAwaiter().GetResult(); HttpClient = BuildHttpClient(); } async Task<Microsoft.Identity.Client.AuthenticationResult> Authentication() { var authBuilder = Microsoft.Identity.Client.PublicClientApplicationBuilder.Create(ClientId) .WithAuthority(Microsoft.Identity.Client.AadAuthorityAudience.AzureAdMultipleOrgs) .WithRedirectUri(RedirectUri) .Build(); string[] scopes = { Resource + "/user_impersonation" }; Microsoft.Identity.Client.AuthenticationResult token = await authBuilder.AcquireTokenInteractive(scopes).ExecuteAsync(); return Token = token; } HttpClient BuildHttpClient() { HttpClient client = new HttpClient() { BaseAddress = BaseAddress, Timeout = new TimeSpan(0, 2, 0) }; System.Net.Http.Headers.HttpRequestHeaders headers = client.DefaultRequestHeaders; headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Token.AccessToken); headers.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); return client; } public async Task<string> PostAsync(string json) { var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await HttpClient.PostAsync(Path, content); string jsonContent = null; if (response.IsSuccessStatusCode) { jsonContent = await response.Content.ReadAsStringAsync(); } return jsonContent ?? ""; } }