20

这个问题与我通过 API 调用的 Microsoft Dynamics CRM 2015 有关。

我创建联系人实体:

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",
  ....
}

接下来我要做的是添加与该联系人关联的注释记录。按照我打电话的指南:

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)'
}

但它返回 400 错误:

未声明的属性“联系人”在有效负载中仅具有属性注释,但在有效负载中未找到属性值。在 OData 中,只有声明的导航属性和声明的命名流可以表示为没有值的属性。

当我打电话时:

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.bindobjectid@odata.bind

有任何想法吗?

4

8 回答 8

21

而不是使用objectid@odata.bind,你必须使用objectid_contact@odata.bind。结果在:

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

要获取属性列表,请查看文档中的单值导航属性。

于 2016-01-05T18:06:05.387 回答
9

我发现这有效,但有两个请求:

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值取自第一个请求的响应。

于 2015-09-25T08:49:12.650 回答
9

第 1 部分:
MS Docs 参考:深度插入

您可以通过将实体定义为导航属性值来创建彼此相关的实体。这称为深插入。与基本创建一样,响应OData-EntityId标头包含已创建实体的 Uri。不返回创建的相关实体的 URI。

下面的代码是创建帐户(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)";

参考SO 链接博客

第 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];

你可以阅读更多

您可以编写 POST 请求,以便从已创建记录中返回的数据将返回状态为 201(已创建)。
要获得此结果,您必须return=representation在请求标头中使用首选项。要控制返回哪些属性,请将 $select 查询选项附加到实体集的 URL。
如果使用 $expand 查询选项将被忽略。当以这种方式创建实体时,OData-EntityId不返回包含创建记录的 URI 的标头

注意:此功能是在 Dynamics 365 的 2016 年 12 月更新中添加的

MS Docs 参考:使用返回的数据创建

更新
如果有人正在寻找工作负载示例以深度插入记录 + 注释,以下来自我的项目:

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,
                }
            ]
    };
于 2017-08-11T21:27:52.080 回答
5

此答案适用于 web api 使用:

如果引用属性已使用大写字母定义,则必须在更新和插入时在属性中使用大写字母。查看主要实体的属性列表中的 Schema 名称。

假设您有myprefix_entity一个引用帐户实体调用的实体,并且您将其命名为Account,并且架构名称变为myprefix_AccountId,您必须将其引用为:

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

大写 A 和大写 I 很myprefix_AccountId重要,如果这是定义模式名称的方式。

于 2017-06-04T19:10:20.390 回答
4

我正在使用这个 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"}
于 2016-01-26T14:43:56.507 回答
1

您可以使用以下。

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

在大多数记录中,您将获得 _contactid_value 作为参数名称。所以你必须像contactid_entityname@odata.bind一样作为参数传递,并且在值中你必须传递'EntitySetName',这将是联系人和GUID。'/EntitysetName(GUID)' 所以值将是 '/contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)'

于 2018-10-11T20:21:48.960 回答
0

这可能有点晚了,但以下链接中的答案解释了绑定如何很好地工作。

基本上,您需要使用带有后缀@odata.bind的字段架构名称,并且值为“/entityschemaname(recordGUID)”很好记住 entityschemaname 需要有一个's'并且 recordGUID不应该有大括号.

欲了解更多信息,请点击下面的链接,我是从那里获得这些信息的

尝试通过 Web API 创建记录时出现“未声明的属性”

于 2018-11-02T09:25:14.100 回答
0

如果您使用 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 对象

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

并简单地调用 InsertEntry 方法。

于 2022-02-14T11:06:23.813 回答