Создание аннотации к объекту контакта в Microsoft Dynamics CRM с помощью 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",
  ....
}

Следующее, что я хочу сделать, это добавить запись аннотации, связанную с этим контактом. Следуя инструкции, я звоню:

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:

Необъявленное свойство 'contact', которое имеет только аннотации свойств в полезной нагрузке, но в полезной нагрузке не найдено значение свойства. В 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.bind, objectid@odata.bind - но без последствий.

Есть идеи?

8 ответов

Решение

Я нашел это работает, но в двух запросах:

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@odata.bind, вы должны использовать objectid_contact@odata.bind, Это результаты в:

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

Чтобы получить список свойств, просмотрите однозначные свойства навигации в документации.

Часть 1:
Справочник по MSDN: Глубокая вставка

Вы можете создавать объекты, связанные друг с другом, определяя их как значения свойств навигации. Это известно как глубокая вставка. Как и в случае базового создания, ответ 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)";

Ссылка так ссылку и блог

Часть 3:
Ответ на ваш комментарий на другой ответ о annotation_id_from_first_request:

Чтобы получить идентификатор созданной записи в ответ на последний запрос, вы можете проанализировать, как показано ниже:

                //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 для созданной записи, не возвращается

Примечание. Эта возможность была добавлена ​​в обновлении за декабрь 2016 года для Dynamics 365.

Справочник по MSDN: создание с возвращенными данными

Обновление:
Если кто-то ищет образец полезной нагрузки для глубокой вставки записи + аннотации, ниже приведен мой проект:

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,
                }
            ]
    };

Этот ответ относится к использованию веб-API:

Если свойство ссылки было определено с использованием заглавных букв, вы должны использовать заглавные буквы в свойстве при обновлении и вставке. Посмотрите на имя схемы в списке свойств основного объекта.

Допустим, у вас есть объект под названием myprefix_entity со ссылкой на сущность учетной записи, и вы назвали его Accountи имя схемы стало myprefix_AccountId, вы должны будете сослаться на это как:

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

Прописные буквы A и Прописные буквы I в myprefix_AccountId имеет значение, если именно так было определено имя схемы.

Я использую этот код 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"}

Вы можете использовать следующее.

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

Может быть немного поздно для этого, но ответ в следующей ссылке объясняет, как действительно хорошо работает привязка.

в основном, вам нужно использовать имя схемы поля с суффиксом @ odata.bind и значением "/entityschemaname(recordGUID)", чтобы помнить, что для entityschemaname нужно использовать 's', а recordGUID не должен иметь фигурных скобок,

для получения дополнительной информации перейдите по этой ссылке ниже, где я получил эту информацию от

"Необъявленное свойство" при попытке создать запись через веб-API

Если вы используете 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.