通过 API 在 Microsoft Dynamics CRM 中为联系人实体创建注释
Create annotation to a contact entity in Microsoft Dynamics CRM by API
此问题与 Microsoft Dynamics CRM 2015 相关,我通过 API 调用。
我创建联系人实体:
POST [organization URI]/api/data/contacts
Content-Type: application/json; charset=utf-8
Accept: application/json
{
"emailaddress1": "myemail@example.com",
}
成功了,我在登录面板后看到了新记录。
我可以通过 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",
....
}
接下来我要做的是添加与该联系人关联的注释记录。
在 guide 之后,我调用:
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)'
}
但是它returns 400错误:
An undeclared property 'contact' which only has property annotations in the payload but no property value was found in the payload. In OData, only declared navigation properties and declared named streams can be represented as properties without values.
当我打电话时:
POST [organization URI]/api/data/annotations
Content-Type: application/json; charset=utf-8
Accept: application/json
{
"notetext": "TEST",
}
新实体已创建,但与联系人无关。
如何正确撰写此 POST 请求?我在这里错过了什么?
我怀疑 contact@odata.bind
应该以某种不同的方式呈现,我试过 contactid@odata.bind
、object@odata.bind
、objectid@odata.bind
- 但没有效果。
有什么想法吗?
我发现它有效,但有两个请求:
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)"
}
编辑:
annotation_id_from_first_request
值取自第一个请求的响应。
您必须使用 objectid_contact@odata.bind
,而不是使用 objectid@odata.bind
。此结果位于:
"objectid_contact@odata.bind": "/contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)"
要获取属性列表,请查看 documentation 中的 single-valued 导航属性。
我正在使用此 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;
JSON 看起来像这样:
{"NoteText":"Hello World!",
"Subject":"Note Subject",
"ObjectId": {"LogicalName":"account",
"Id":"003CCFC2-4012-DE11-9654-001F2964595C"}
,"ObjectTypeCode":"account"}
此答案适用于网络 api 用法:
如果引用 属性 已使用大写字母定义,则在更新和插入时必须在 属性 中使用大写字母。查看主要实体的 属性 列表中的架构名称。
假设您有一个名为 myprefix_entity
的实体,其中包含对帐户实体的引用,您将其命名为 Account
,并且架构名称变为 myprefix_AccountId
,您必须将其称为:
"myprefix_AccountId@odata.bind":"/accounts(f76e4e7c-ea61-e511-80fd-000000000000)"
myprefix_AccountId
中的大写 A 和大写 I 很重要,如果模式名称是这样定义的。
第 1 部分:
MS 文档参考:Deep Insert
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. The URIs for the related entities created aren’t returned.
下面的代码是创建帐户 (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" }
]
}
]
}
第 2 部分:
将注释关联到联系人使用以下语法。
note["objectid_contact@odata.bind"] = "/contacts(C5DDA727-B375-E611-80C8-00155D00083F)";
参考 & blog
第 3 部分:
回答您对另一个关于 annotation_id_from_first_request
的回答的评论:
要获取响应上次请求的创建记录Id,您可以像下面这样解析:
//get Response from Created Record
entityIdWithLink = XMLHttpRequest.getResponseHeader("OData-EntityId");
//get EntityId from ResponseHeader of Created Record
getEntityId = entityIdWithLink.split(/[()]/);
getEntityId = getEntityId[1];
你可以read more
You can compose your POST request so that data from the created record will be returned with a status of 201 (Created).
To get this result, you must use the return=representation
preference in the request headers.
To control which properties are returned, append the $select query option to the URL to the entity set.
The $expand query option will be ignored if used.
When an entity is created in this way the OData-EntityId
header containing the URI to the created record is not returned
Note: This capability was added with December 2016 update for Dynamics 365
MS 文档参考:Create with data returned
更新:
如果有人在寻找工作负载样本来深入插入记录+注释,下面是我的项目:
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,
}
]
};
您可以使用以下内容。
'contactid_contact@odata.bind': '/contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)'
在大多数记录中,您会得到 _contactid_value 作为参数名称。因此,您必须像 contactid_entityname@odata.bind 作为参数传递,并且在值中您必须传递 'EntitySetName',即 contacts 和 GUID。 '/实体集名称(GUID)'
所以该值将是 '/contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)'
这可能有点晚了,但下面的答案 link 解释了绑定如何很好地工作。
基本上,您需要使用带有后缀 @odata.bind 且值为 "/entityschemaname(recordGUID)" 记住 entityschemaname 需要有一个 's' 而 recordGUID 不应该有大括号。
要了解更多信息,请关注下方的 link,我从
那里获得了这些信息
如果你使用OData,那么你可以这样做...
在您的注释数据模型中:
[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!;
其中 rd_servicerequestsession 是您的实体名称。那么你只需要新建一个对象Annotation object
var annotation = new Annotation
{
ObjectId = serviceRequestSession,
ObjectTypeCode = "rd_servicerequestsession",
然后只需调用 InsertEntry 方法。
此问题与 Microsoft Dynamics CRM 2015 相关,我通过 API 调用。
我创建联系人实体:
POST [organization URI]/api/data/contacts
Content-Type: application/json; charset=utf-8
Accept: application/json
{
"emailaddress1": "myemail@example.com",
}
成功了,我在登录面板后看到了新记录。 我可以通过 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",
....
}
接下来我要做的是添加与该联系人关联的注释记录。 在 guide 之后,我调用:
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)'
}
但是它returns 400错误:
An undeclared property 'contact' which only has property annotations in the payload but no property value was found in the payload. In OData, only declared navigation properties and declared named streams can be represented as properties without values.
当我打电话时:
POST [organization URI]/api/data/annotations
Content-Type: application/json; charset=utf-8
Accept: application/json
{
"notetext": "TEST",
}
新实体已创建,但与联系人无关。
如何正确撰写此 POST 请求?我在这里错过了什么?
我怀疑 contact@odata.bind
应该以某种不同的方式呈现,我试过 contactid@odata.bind
、object@odata.bind
、objectid@odata.bind
- 但没有效果。
有什么想法吗?
我发现它有效,但有两个请求:
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)"
}
编辑:
annotation_id_from_first_request
值取自第一个请求的响应。
您必须使用 objectid_contact@odata.bind
,而不是使用 objectid@odata.bind
。此结果位于:
"objectid_contact@odata.bind": "/contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)"
要获取属性列表,请查看 documentation 中的 single-valued 导航属性。
我正在使用此 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;
JSON 看起来像这样:
{"NoteText":"Hello World!",
"Subject":"Note Subject",
"ObjectId": {"LogicalName":"account",
"Id":"003CCFC2-4012-DE11-9654-001F2964595C"}
,"ObjectTypeCode":"account"}
此答案适用于网络 api 用法:
如果引用 属性 已使用大写字母定义,则在更新和插入时必须在 属性 中使用大写字母。查看主要实体的 属性 列表中的架构名称。
假设您有一个名为 myprefix_entity
的实体,其中包含对帐户实体的引用,您将其命名为 Account
,并且架构名称变为 myprefix_AccountId
,您必须将其称为:
"myprefix_AccountId@odata.bind":"/accounts(f76e4e7c-ea61-e511-80fd-000000000000)"
myprefix_AccountId
中的大写 A 和大写 I 很重要,如果模式名称是这样定义的。
第 1 部分:
MS 文档参考:Deep Insert
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. The URIs for the related entities created aren’t returned.
下面的代码是创建帐户 (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" }
]
}
]
}
第 2 部分:
将注释关联到联系人使用以下语法。
note["objectid_contact@odata.bind"] = "/contacts(C5DDA727-B375-E611-80C8-00155D00083F)";
参考
第 3 部分:
回答您对另一个关于 annotation_id_from_first_request
的回答的评论:
要获取响应上次请求的创建记录Id,您可以像下面这样解析:
//get Response from Created Record
entityIdWithLink = XMLHttpRequest.getResponseHeader("OData-EntityId");
//get EntityId from ResponseHeader of Created Record
getEntityId = entityIdWithLink.split(/[()]/);
getEntityId = getEntityId[1];
你可以read more
You can compose your POST request so that data from the created record will be returned with a status of 201 (Created).
To get this result, you must use thereturn=representation
preference in the request headers. To control which properties are returned, append the $select query option to the URL to the entity set.
The $expand query option will be ignored if used. When an entity is created in this way theOData-EntityId
header containing the URI to the created record is not returned
Note: This capability was added with December 2016 update for Dynamics 365
MS 文档参考:Create with data returned
更新:
如果有人在寻找工作负载样本来深入插入记录+注释,下面是我的项目:
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,
}
]
};
您可以使用以下内容。
'contactid_contact@odata.bind': '/contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)'
在大多数记录中,您会得到 _contactid_value 作为参数名称。因此,您必须像 contactid_entityname@odata.bind 作为参数传递,并且在值中您必须传递 'EntitySetName',即 contacts 和 GUID。 '/实体集名称(GUID)' 所以该值将是 '/contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)'
这可能有点晚了,但下面的答案 link 解释了绑定如何很好地工作。
基本上,您需要使用带有后缀 @odata.bind 且值为 "/entityschemaname(recordGUID)" 记住 entityschemaname 需要有一个 's' 而 recordGUID 不应该有大括号。
要了解更多信息,请关注下方的 link,我从
那里获得了这些信息如果你使用OData,那么你可以这样做...
在您的注释数据模型中:
[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!;
其中 rd_servicerequestsession 是您的实体名称。那么你只需要新建一个对象Annotation object
var annotation = new Annotation
{
ObjectId = serviceRequestSession,
ObjectTypeCode = "rd_servicerequestsession",
然后只需调用 InsertEntry 方法。