web-dev-qa-db-ja.com

既存のすべてのフィールドのメタデータをクエリする方法

クライアントが次のようなエンドポイントに投稿できるようにします。

    [Route("Account", Name = "CreateAccount", Order = 1)]
    [HttpPost]
    public Account CreateAccount([FromBody] Account account)
    {
        var newAccount = _accountService.CreateAccountEntity(account);
        return newAccount;
    }

私たち 知っている これができること:

POST [Organization URI]/api/data/v8.2/accounts HTTP/1.1
Content-Type: application/json; charset=utf-8
OData-MaxVersion: 4.0
OData-Version: 4.0
Accept: application/json

{
    "name": "Sample Account",
    "creditonhold": false,
    "address1_latitude": 47.639583,
    "description": "This is the description of the sample account",
    "revenue": 5000000,
    "accountcategorycode": 1
}

各投稿/プットの要件を消費者にどのように公開しますか?

別の言い方をすれば、CRM2016で提供されているWebAPIを使用してカスタムエンティティまたはベースエンティティのレコードを更新する必要がある場合、作成または更新するために必要なフィールドを知るにはどうすればよいですか?エンティティ?

編集:ハンクのアプローチを試みましたが、エンティティのメタデータが返されませんでした: enter image description here

[〜#〜] sdk [〜#〜] に示すように、WebApiエンドポイントを使用してDynamics365メタデータをクエリできます。

たとえば、accountエンティティのすべての属性(要件レベルを含む)を取得するには、次のようにします。

GET [Organization URI]/api/data/v8.2/EntityDefinitions(LogicalName='account')/Attributes HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
Accept: application/json
Content-Type: application/json; charset=utf-8
10
Nicknow

RetrieveEntityRequestを使用して、エンティティのメタデータを取得できます。

次の例では、エンティティAccountのメタデータが取得されます。

var request = new RetrieveEntityRequest
{
    EntityFilters = EntityFilters.Entity | EntityFilters.Attributes,
    LogicalName = "account"
};

var response = (RetrieveEntityResponse)_serviceProxy.Execute(request);

応答オブジェクトにはEntityMetadataプロパティが含まれています。その中には、次のような属性の要件設定があります。

EntityMetadata metadata = reponse.EntityMetadata;
bool isRevenueRequired = metadata.Attributes
    .First<AttributeMetadata>(a -> a.LogicalName == "revenue")
    .RequiredLevel.Value == AttributeRequiredLevel.ApplicationRequired;
6

SOAPエンドポイントを使用してエンティティのすべてのメタデータを取得するには、RetrieveEntityRequestを使用できます。

 var request = new RetrieveEntityRequest
 {
       EntityFilters = Microsoft.Xrm.Sdk.Metadata.EntityFilters.All,
       LogicalName = "account"
 }

 var response = (RetrieveEntityResponse)organizationService.Execute(request); 

EntityFitersは、取得しようとしているメタデータを指定できる列挙型です。

[Flags]
public enum EntityFilters
{
    //
    // Summary:
    //     Use this to retrieve only entity information. Equivalent to EntityFilters.Default.
    //     Value = 1.
    Entity = 1,
    //
    // Summary:
    //     Use this to retrieve only entity information. Equivalent to EntityFilters.Entity.
    //     Value = 1.
    Default = 1,
    //
    // Summary:
    //     Use this to retrieve entity information plus attributes for the entity. Value
    //     = 2.
    Attributes = 2,
    //
    // Summary:
    //     Use this to retrieve entity information plus privileges for the entity. Value
    //     = 4.
    Privileges = 4,
    //
    // Summary:
    //     Use this to retrieve entity information plus entity relationships for the entity.
    //     Value = 8.
    Relationships = 8,
    //
    // Summary:
    //     Use this to retrieve all data for an entity. Value = 15.
    All = 15
}

これはフラグ列挙型なので、次のように使用できます。

var request = new RetrieveEntityRequest
{
     EntityFilters = EntityFilters.Privileges | EntityFilters.Entity,
     LogicalName = "account"
} 

または、単にAll値を使用して、必要なすべてのメタデータを取得します。エンティティメタデータのみを要求し、属性メタデータに関心があるため、メタデータの取得に失敗しました。

したがって、コードスニペットをベースとして、これを次のように使用します。

[Route("Account", Name = "CreateAccount", Order = 1)]
[HttpPost]
public Account CreateAccount([FromBody] Account account)
{
    VerifyRequiredFields(account);
    var newAccount = _accountService.CreateAccountEntity(account);
    return newAccount;
}

private void VerifyRequiredFields(Account account)
{
     var response = GetEntityMetadata(account);
     var requiredAttributes = response.EntityMetadata.Attributes.Where(a => a.RequiredLevel?.Value == AttributeRequiredLevel.SystemRequired);
     foreach(var requiredAttribute in requiredAttributes)
     {
          if(CheckIfValueIsProvided(requiredAttribute.LogicalName, account))
          {
               throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, $"You are missing required value {requiredAttribute.LogicalName}"));
          }
     }
}

メソッドGetEntityMetadataは単に前の例と同じことをしているので、RetrieveEntityRequestを呼び出してRetrieveEntityResponseを返します。もちろん、メソッドCheckIfValueIsProvidedの実装は、アカウントモデルクラスの定義方法によって異なりますが、モデルとCRMエンティティモデルの間の何らかのマッピングが必要になる可能性があります(たとえば、フィールド「accountnumber」のマッピング方法を知るため)。モデルの一部のフィールドに)。これはこの質問の範囲をはるかに超えていますが、あなたはすでに始めるのに十分知っていると思います。これは単なる例であることを忘れないでください。このロジックをコントローラークラス内に保持するのではなく、別のコントローラーで再利用できるユーティリティクラスに移動する必要があります。メタデータは頻繁に変更されないため(おそらくこの変更を制御できます)、Webアプリケーションなどのどこかにメタデータをキャッシュすることもできます。何ができるかについてはすでに理解していると思いますが、全体の設計ロジックが別の話の場合。

JavaScriptからこれを実行したい場合は、おそらくwebAPIに固執する必要があります。

http://CRMADDRESS/api/data/v8.2/EntityDefinitions(LogicalName='account')/Attributes?$select=LogicalName,RequiredLevel

必要なもの(属性の名前とその必須レベル)を取得します。次のようになります。

{
  "LogicalName":"preferredcontactmethodcodename","RequiredLevel":{
    "Value":"None","CanBeChanged":false,"ManagedPropertyLogicalName":"canmodifyrequirementlevelsettings"
  },"MetadataId":"8663b910-af86-4dea-826e-8222706372f4"
},{
  "@odata.type":"#Microsoft.Dynamics.CRM.StringAttributeMetadata","LogicalName":"emailaddress3","RequiredLevel":{
    "Value":"None","CanBeChanged":true,"ManagedPropertyLogicalName":"canmodifyrequirementlevelsettings"
  },"MetadataId":"97fb4aae-ea5d-427f-9b2b-9a6b9754286e"
},{
  "@odata.type":"#Microsoft.Dynamics.CRM.StringAttributeMetadata","LogicalName":"emailaddress2","RequiredLevel":{
    "Value":"None","CanBeChanged":true,"ManagedPropertyLogicalName":"canmodifyrequirementlevelsettings"
  },"MetadataId":"98b09426-95ab-4f21-87a0-f6775f2b4210"
},{
  "@odata.type":"#Microsoft.Dynamics.CRM.StringAttributeMetadata","LogicalName":"emailaddress1","RequiredLevel":{
    "Value":"None","CanBeChanged":true,"ManagedPropertyLogicalName":"canmodifyrequirementlevelsettings"
  },"MetadataId":"b254ab69-de5a-4edb-8059-bdeb6863c544"
},{
  "@odata.type":"#Microsoft.Dynamics.CRM.StringAttributeMetadata","LogicalName":"masteraccountidyominame","RequiredLevel":{
    "Value":"None","CanBeChanged":false,"ManagedPropertyLogicalName":"canmodifyrequirementlevelsettings"
  },"MetadataId":"a15dedfc-9382-43ac-8d10-7773aa3eefeb"
},{
  "@odata.type":"#Microsoft.Dynamics.CRM.StringAttributeMetadata","LogicalName":"address1_city","RequiredLevel":{
    "Value":"None","CanBeChanged":true,"ManagedPropertyLogicalName":"canmodifyrequirementlevelsettings"
  },"MetadataId":"ca8d0a94-8569-4154-b511-718e11635449"
},{
  "@odata.type":"#Microsoft.Dynamics.CRM.LookupAttributeMetadata","LogicalName":"slaid","RequiredLevel":{
    "Value":"None","CanBeChanged":true,"ManagedPropertyLogicalName":"canmodifyrequirementlevelsettings"
  },"MetadataId":"6bdcd7f1-5865-4fef-91b0-676824b18641"
}

これを使用して、クライアント側で要求を検証し、サーバーに要求を送信する前に、重要なデータが欠落しているというヒントをユーザーに与えることができます。

6
Pawel Gradecki