简体   繁体   English

通过 API 在 Microsoft Dynamics CRM 中为联系人实体创建注释

[英]Create annotation to a contact entity in Microsoft Dynamics CRM by API

This question is related to Microsoft Dynamics CRM 2015, that I'm calling through API.这个问题与我通过 API 呼叫的 Microsoft Dynamics CRM 2015 有关。

I create contact entity:我创建联系人实体:

POST [organization URI]/api/data/contacts
Content-Type: application/json; charset=utf-8
Accept: application/json
{
    "emailaddress1": "myemail@example.com",
}

It works, I see new record, after I log into the panel.它有效,我在登录面板后看到新记录。 And I can call it through the API:我可以通过 API 呼叫它:

[organization URI]/api/data/contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)
{
  "@odata.context":"[organization URI]/api/data/$metadata#contacts/$entity",
  "@odata.etag":"W/\"460199\"",
  ...
  "contactid":"f76e4e7c-ea61-e511-80fd-3863bb342b00",
  "emailaddress1":"myemail@example.com",
  ....
}

Next thing I want to do, is to add annotation record associated with that contact.接下来我要做的是添加与该联系人关联的注释记录。 Following the guide I call:按照指南,我打电话给:

POST [organization URI]/api/data/annotations
Content-Type: application/json; charset=utf-8
Accept: application/json
{
    "notetext": "TEST",
    'contact@odata.bind': 'contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)'
}

But it returns 400 error:但它返回 400 错误:

An undeclared property 'contact' which only has property annotations in the payload but no property value was found in the payload.未声明的属性“contact”在有效负载中只有属性注释,但在有效负载中找不到属性值。 In OData, only declared navigation properties and declared named streams can be represented as properties without values.在 OData 中,只有声明的导航属性和声明的命名流可以表示为没有值的属性。

When I call:当我打电话时:

POST [organization URI]/api/data/annotations
Content-Type: application/json; charset=utf-8
Accept: application/json
{
    "notetext": "TEST",
}

New entity is created, but without a relation to contact.新实体已创建,但与联系人无关。

How to properly compose this POST request?如何正确编写此 POST 请求? What am I missing here?我在这里错过了什么? I suspect, that contact@odata.bind should be presented somehow different, I've tried contactid@odata.bind , object@odata.bind , objectid@odata.bind - but no effects.我怀疑contact@odata.bind应该以某种不同的方式呈现,我已经尝试过contactid@odata.bindobject@odata.bindobjectid@odata.bind - 但没有效果。

Any ideas?有任何想法吗?

Instead of using objectid@odata.bind , you have to use objectid_contact@odata.bind .而不是使用的objectid@odata.bind ,你必须使用objectid_contact@odata.bind This results are in:结果是:

"objectid_contact@odata.bind": "/contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)"

To get the list of properties, look under the single-valued navigation properties in the documentation .要获取属性列表,请查看文档中的单值导航属性。

I've found this working, but in two requests:我发现这有效,但有两个请求:

POST [organization URI]/api/data/annotations
Content-Type: application/json; charset=utf-8
Accept: application/json
{
    "notetext": "TEST"
}

POST [organization URI]/api/data/contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)/Contact_Annotation/$ref
Content-Type: application/json; charset=utf-8
Accept: application/json
{
    "@odata.id": "[organization URI]/annotations(annotation_id_from_first_request)"
}

Edit:编辑:

annotation_id_from_first_request value is taken form first request's response. annotation_id_from_first_request值取自第一个请求的响应。

Part 1:第1部分:
MSDN Reference: Deep Insert MSDN 参考: 深度插入

You can create entities related to each other by defining them as navigation properties values.您可以通过将实体定义为导航属性值来创建彼此相关的实体。 This is known as deep insert .这称为深插入 As with a basic create, the response OData-EntityId header contains the Uri of the created entity.与基本创建一样,响应OData-EntityId标头包含所创建实体的 Uri。 The URIs for the related entities created aren't returned.不返回创建的相关实体的 URI。

Below code is to create Account (1), create + associate Primary contact (2), create & Associate Opportunity (3) and create + associate Task (4)下面的代码是创建帐户(1),创建+关联主要联系人(2),创建和关联机会(3)和创建+关联任务(4)

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",
 "primarycontactid":
 {
     "firstname": "John",
     "lastname": "Smith"
 },
 "opportunity_customer_accounts":
 [
  {
      "name": "Opportunity associated to Sample Account",
      "Opportunity_Tasks":
      [
       { "subject": "Task associated to opportunity" }
      ]
  }
 ]
}

Part 2:第2部分:
Associating annotation to contact uses the below syntax.将注释与联系人相关联使用以下语法。

note["objectid_contact@odata.bind"] = "/contacts(C5DDA727-B375-E611-80C8-00155D00083F)";

Refer SO link & blog参考SO 链接博客

Part 3:第 3 部分:
Answer to your comment on another answer about annotation_id_from_first_request :回答您对annotation_id_from_first_request另一个答案的评论:

To get the created record Id in response from last request, you can parse like below:要从上次请求中获取创建的记录 ID,您可以像下面这样解析:

                //get Response from Created Record
                entityIdWithLink = XMLHttpRequest.getResponseHeader("OData-EntityId");

                //get EntityId from ResponseHeader of Created Record  
                getEntityId = entityIdWithLink.split(/[()]/);
                getEntityId = getEntityId[1];

You can read more你可以阅读更多

You can compose your POST request so that data from the created record will be returned with a status of 201 (Created).您可以编写您的 POST 请求,以便来自已创建记录的数据将以 201(已创建)状态返回。
To get this result, you must use the return=representation preference in the request headers.要获得此结果,您必须在请求标头中使用return=representation首选项。 To control which properties are returned, append the $select query option to the URL to the entity set.要控制返回哪些属性,请将 $select 查询选项附加到实体集的 URL。
The $expand query option will be ignored if used.如果使用 $expand 查询选项将被忽略。 When an entity is created in this way the OData-EntityId header containing the URI to the created record is not returned以这种方式创建实体时,不会返回包含所创建记录的 URI 的OData-EntityId标头

Note : This capability was added with December 2016 update for Dynamics 365注意:此功能是随 Dynamics 365 的 2016 年 12 月更新添加的

MSDN Reference: Create with data returned MSDN 参考: 使用返回的数据创建

Update :更新
If anyone looking for working payload sample to deep insert a record + annotation, the below is from my project:如果有人正在寻找有效负载示例以深入插入记录 + 注释,以下内容来自我的项目:

data = {
        "new_attribute1": "test attribute 1",
        "new_attribute2": "test attribute 2",
        "new_comments": "test comments",
        "new_recordurl": recordURL,
        "new_feedback_Annotations":
            [
                {
                    "notetext": "Screenshot attached",
                    "subject": "Attachment",
                    "filename": file.name,
                    "mimetype": file.type,
                    "documentbody": base64str,
                }
            ]
    };

This answer applies for web api usage:此答案适用于 web api 使用:

If the references property has been defined using uppercase letters, you have to use uppercase letters in the property on update and insert.如果已使用大写字母定义了references 属性,则必须在更新和插入时在属性中使用大写字母。 Look at the Schema name in the property list of the primary entity.查看主要实体的属性列表中的架构名称。

Lets say you have an entity called myprefix_entity with a reference to the account entity, and you named it Account , and the schema name became myprefix_AccountId , you would have to refer it as:假设您有一个名为myprefix_entity的实体,并引用了帐户实体,并将其命名为Account ,架构名称变为myprefix_AccountId ,您必须将其引用为:

"myprefix_AccountId@odata.bind":"/accounts(f76e4e7c-ea61-e511-80fd-000000000000)"

The uppercase A and the uppercase I in myprefix_AccountId matters, if that is how the schema name has been defined. myprefix_AccountId的大写 A 和大写 I myprefix_AccountId重要,如果架构名称是这样定义的。

I'm using this C# Code for creating and linking (the Task.Await stuff is not very clever, so... be careful):我使用这个 C# 代码来创建和链接(Task.Await 的东西不是很聪明,所以......小心):

dynamic testAno = new ExpandoObject();
testAno.NoteText = "Hello World!";
testAno.Subject = "Note Subject";

dynamic refAccount = new ExpandoObject();
refAccount.LogicalName = "account";
refAccount.Id = "003CCFC2-4012-DE11-9654-001F2964595C";

testAno.ObjectId = refAccount;
testAno.ObjectTypeCode = refAccount.LogicalName;

var demo = JsonConvert.SerializeObject(testAno);

HttpContent content = new StringContent(demo, Encoding.UTF8, "application/json");

var handler = new HttpClientHandler { UseDefaultCredentials = true };

HttpClient client = new HttpClient(handler);
var test = client.PostAsync(new Uri("http://crm/.../XRMServices/2011/OrganizationData.svc/AnnotationSet"), content).Result;

The JSON is looking like this: JSON 看起来像这样:

{"NoteText":"Hello World!",
 "Subject":"Note Subject",
 "ObjectId": {"LogicalName":"account",
              "Id":"003CCFC2-4012-DE11-9654-001F2964595C"}
,"ObjectTypeCode":"account"}

You can use following.您可以使用以下内容。

'contactid_contact@odata.bind': '/contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)'

In most of the record you will get _contactid_value as a parameter name.在大多数记录中,您将获得 _contactid_value 作为参数名称。 So you have to pass like contactid_entityname@odata.bind as a parameter and in the value you have to pass 'EntitySetName' which would be contacts and GUID.所以你必须像contactid_entityname@odata.bind一样传递一个参数,在你必须传递的值中,你必须传递'EntitySetName',这将是联系人和GUID。 '/EntitysetName(GUID)' So the value will be '/contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)' '/EntitysetName(GUID)' 所以值将是 '/contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)'

might be a bit late for this, but the answer in the following link explains how the binding works really well.对此可能有点晚,但以下链接中的答案解释了绑定如何真正有效地工作。

basically, you need to use the field schema name with the suffix @odata.bind and the value being "/entityschemaname(recordGUID)" good to remember that the entityschemaname needs to have an 's' and the recordGUID should not have the curly brackets.基本上,您需要使用带有后缀@odata.bind字段架构名称,并且值为“/entityschemaname(recordGUID)”记住entityschemaname 需要有一个's'并且recordGUID不应该有大括号.

for more information follow this link below where i got this information from有关更多信息,请点击下面的链接,我是从那里获得此信息的

'An undeclared property' when trying to create record via Web API 尝试通过 Web API 创建记录时出现“未声明的属性”

If you use OData, then you can do it this way...如果你使用 OData,那么你可以这样做......

In your Annotation data model:在您的注释数据 model 中:

[DataContract(Name = "annotations")]
public record Annotation
{
    [DataMember(Name = "objectid_rd_servicerequestsession")]
    public ServiceRequestSession ObjectId { get; set; } = default!;

    [DataMember(Name = "objecttypecode")]
    public string ObjectTypeCode { get; set; } = default!;

Where the rd_servicerequestsession is your entity name.其中 rd_servicerequestsession 是您的实体名称。 Then you just need to create a new object Annotation object那么你只需要新建一个 object 注解 object

    var annotation = new Annotation
    {
        ObjectId = serviceRequestSession,
        ObjectTypeCode = "rd_servicerequestsession",

And simply invoke InsertEntry method.并简单地调用 InsertEntry 方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM