Dynamics CRM 4.0でエンティティのデータを操作するのではなく、エンティティや属性のメタデータを使用する場合はメタデータサービス(MetadataService) を使用します。今回の記事では、エンティティや属性のメタデータを作成、更新および削除をするサンプルを掲載します。
サンプルの動作確認はIFD構成の環境で行っています。IFD構成やAD構成のMetadataServiceインスタンスの作成方法の詳細は、[DynamicsCRM] MetadaServiceを使用してエンティティのメタデータを取得する を参照してください。
動作確認環境
- 確認環境:Windows Server 2003 に IFD構成の Dynamics CRM 4.0をインストール
- 開発環境:Visual Studio 2008 Professional
- .NET 3.0
1. ソリューションの作成
Visual Studio を起動し、空のソリューションを作成します。本サンプルはコンソールアプリケーションとして開発します。ソリューションエクスプローラを右クリックし、コンソールプロジェクトを追加します。動作には、Dynamics CRM SDK に付属する、microsoft.crm.sdk.dll、microsoft.crm.sdktypeproxy.dllおよび、System.Web.Service.dll の参照が必要ですので、プロジェクトの参照で追加してします。
1.1 CrmDiscoveryService 用プロキシクラスの作成
IFD構成では、一度CrmDiscovryServiceに接続して認証トークンを取得した後、MetadataService を作成します。そのため、 CrmDiscoveryService を使用できるように、Dynamics CRM SDK に付属するwsdlフォルダのcrmdiscoveryservice.wsdlからプロキシクラスを作成します。
プロキシクラスは次のSDKのwsdlフォルダに移動して次のコマンドで作成しました。
wsdl /namespace:Microsoft.Crm.Sdk.Discovery crmdiscoveryservice.wsdl
作成したプロキシクラスCrmDiscoveryService.csをプロジェクトに含めます。
2.MetadataServiceの作成プログラム
IFD構成のメタデータサービスは次のプログラムで作成します。AD認証の場合は[DynamicsCRM] MetadaServiceを使用してエンティティのメタデータを取得する で紹介されているGetMetadataService メソッドを参照してください。
/// <summary>
/// IFD構成用
/// </summary>
/// <param name="discoveryServerUrl"></param>
/// <param name="organizationName"></param>
/// <param name="domain"></param>
/// <param name="username"></param>
/// <param name="password"></param>
/// <returns></returns>
public static MetadataService GetMetadataServiceByIFD(string discoveryServerUrl, string organizationName, string domain, string username, string password)
{
string userid = domain + @"\" + username;
UriBuilder uriBuilder = new UriBuilder(discoveryServerUrl);
uriBuilder.Path = "/MSCRMServices/2007/SPLA/CrmDiscoveryService.asmx";
CrmDiscoveryService disco = new CrmDiscoveryService();
disco.Url = uriBuilder.Uri.ToString();
disco.UseDefaultCredentials = false;
disco.Credentials = new NetworkCredential(username, password, domain);
RetrieveOrganizationsRequest orgRequest = new RetrieveOrganizationsRequest();
orgRequest.UserId = userid;
orgRequest.Password = password;
RetrieveOrganizationsResponse orgResponse =
(RetrieveOrganizationsResponse)disco.Execute(orgRequest);
bool found = false;
string serviceUrl = string.Empty;
string metadataServiceUrl = string.Empty;
foreach (OrganizationDetail orgdetail in orgResponse.OrganizationDetails)
{
if (orgdetail.OrganizationName == organizationName)
{
found = true;
serviceUrl = orgdetail.CrmServiceUrl;
metadataServiceUrl = orgdetail.CrmMetadataServiceUrl;
break;
}
}
if (found == false) return null;
RetrieveCrmTicketRequest ticketRequest = new RetrieveCrmTicketRequest();
ticketRequest.OrganizationName = organizationName;
ticketRequest.UserId = userid;
ticketRequest.Password = password;
RetrieveCrmTicketResponse ticketResponse =
(RetrieveCrmTicketResponse)disco.Execute(ticketRequest);
CrmAuthenticationToken token = new CrmAuthenticationToken();
token.AuthenticationType = 2; // IFD, ADの場合0
token.OrganizationName = organizationName;
token.CrmTicket = ticketResponse.CrmTicket;
MetadataService service = new MetadataService();
service.Url = metadataServiceUrl;
service.CrmAuthenticationTokenValue = token;
service.UseDefaultCredentials = true;
return service;
}
3. カスタムエンティティと属性のメタデータの操作
new_zaikoというスキーマ名のカスタムエンティティのメタデータを操作します。
3.1 カスタムエンティティの作成
new_zaikoというカスタムエンティティを使用します。CrmLabelクラス作成用のユーティリティメソッドも定義します。
/// <summary>
/// 在庫エンティティを作成する
/// </summary>
/// <param name="service"></param>
public static void CreateCustomEntity(MetadataService service)
{
EntityMetadata metadata = new EntityMetadata();
metadata.SchemaName = "new_zaiko";
metadata.DisplayName = CreateCrmLabel("在庫");
metadata.DisplayCollectionName = CreateCrmLabel("在庫(複数)");
metadata.Description = CreateCrmLabel("在庫の説明");
// エンティティのデータはユーザ所有
metadata.OwnershipType = new CrmOwnershipTypes(OwnershipTypes.UserOwned);
StringAttributeMetadata stringMetadata = new StringAttributeMetadata();
stringMetadata.SchemaName = "new_name";
stringMetadata.DisplayName = CreateCrmLabel("商品");
stringMetadata.Description = CreateCrmLabel("商品の説明");
stringMetadata.RequiredLevel = new CrmAttributeRequiredLevel(AttributeRequiredLevel.Required);
stringMetadata.MaxLength = new CrmNumber(50);
CreateEntityRequest request = new CreateEntityRequest();
request.Entity = metadata;
request.PrimaryAttribute = stringMetadata;
request.HasNotes = true;
CreateEntityResponse response = (CreateEntityResponse) service.Execute(request);
Console.WriteLine(response.EntityId.Value);
}
public static CrmLabel CreateCrmLabel(string label)
{
int languageCode = 1041;
CrmLabel crmlabel = new CrmLabel();
crmlabel.LocLabels = new LocLabel[] { new LocLabel(label, new CrmNumber(languageCode)) };
return crmlabel;
}
3.2 カスタムエンティティメタデータの更新
カスタムエンティティのメタデータDisplayNameを変更します。カスタムエンティティのメタデータは変更できる項目は限られています。
/// <summary>
/// エンティティを更新する
/// Description, DisplayCollectionName,DisplayName,DuplicateDetection,IsAvailableOffline
/// のみ更新可能
/// </summary>
/// <param name="service"></param>
public static void UpdateCustomEntity(MetadataService service)
{
EntityMetadata metadata = new EntityMetadata();
metadata.LogicalName = "new_zaiko";
metadata.DisplayName = CreateCrmLabel("在庫2");
UpdateEntityRequest request = new UpdateEntityRequest();
request.Entity = metadata;
service.Execute(request);
}
3.3 カスタムエンティティの削除
/// <summary>
/// エンティティを削除する
/// </summary>
/// <param name="service"></param>
public static void DeleteCustomEntity(MetadataService service)
{
DeleteEntityRequest request = new DeleteEntityRequest();
request.LogicalName = "new_zaiko";
service.Execute(request);
}
3.3 属性メタデータの作成
new_booleanという属性をカスタムエンティティnew_zaikoに追加します。
/// <summary>
/// 属性を追加する
/// </summary>
/// <param name="service"></param>
public static void AddCustomEntityAttribute(MetadataService service)
{
BooleanAttributeMetadata booleanMetadata = new BooleanAttributeMetadata();
booleanMetadata.SchemaName = "new_boolean";
booleanMetadata.DisplayName = CreateCrmLabel("真偽値");
booleanMetadata.Description = CreateCrmLabel("真偽値属性です");
booleanMetadata.RequiredLevel = new CrmAttributeRequiredLevel(AttributeRequiredLevel.Recommended);
booleanMetadata.TrueOption = new Option();
booleanMetadata.TrueOption.Value = new CrmNumber(1);
booleanMetadata.TrueOption.Label = CreateCrmLabel("はい");
booleanMetadata.FalseOption = new Option();
booleanMetadata.FalseOption.Value = new CrmNumber(0);
booleanMetadata.FalseOption.Label = CreateCrmLabel("いいえ");
CreateAttributeRequest request = new CreateAttributeRequest();
request.EntityName = "new_zaiko";
request.Attribute = booleanMetadata;
service.Execute(request);
}
3.4 属性メタデータの更新
属性new_nameのメタデータを更新します。
/// <summary>
/// スキーマ名new_nameのロジカル名(スキーマ名をすべて小文字)を指定して
/// 属性を更新
/// </summary>
/// <param name="service"></param>
public static void UpdateCustomEntityAttribute(MetadataService service)
{
StringAttributeMetadata stringMetadata = new StringAttributeMetadata();
stringMetadata.LogicalName = "new_name";
stringMetadata.DisplayName = CreateCrmLabel("商品/備品");
stringMetadata.Description = CreateCrmLabel("商品/備品の説明");
// 属性を追加
UpdateAttributeRequest request = new UpdateAttributeRequest();
request.EntityName = "new_zaiko";
request.Attribute = stringMetadata;
service.Execute(request);
}
3.4 実行処理
カスタムエンティティを作成、メタデータの操作、エンティティの削除をする一連の処理を行うようにMainメソッドを記述して実行し、動作することを確認します。
static void Main(string[] args)
{
MetadataService service = GetMetadataServiceByIFD("http://crmorg02.vs2k3.crm.local/", "crmorg02", "crm", "admin", "password");
CreateCustomEntity(service);
UpdateCustomEntityAttribute(service);
AddCustomEntityAttribute(service);
UpdateCustomEntity(service);
//DeleteCustomEntity(service);
Console.ReadLine();
}
4. まとめ
説明は以上です。メタデータサービスを使用すると、カスタムアプリケーションでエンティティや属性のメタデータを操作できるようになります。ちなみにサンプルには掲載していませんが、属性の削除は DeleteAttributeRequest クラスを使用します。
さんのコメント: さんのコメント: