Создание аннотации к объекту контакта в 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.