public Task <Message> PostMessageAsync(string authToken, MessageToPost msg, string operationId = null) { var qsb = new PathAndQueryBuilder("/V3/PostMessage"); qsb.AddParameter("operationId", operationId); return(PerformHttpRequestAsync <MessageToPost, Message>(authToken, qsb.BuildPathAndQuery(), msg)); }
public Message PostMessage(string authToken, MessageToPost msg, string operationId = null) { if (authToken == null) { throw new ArgumentNullException("authToken"); } if (msg == null) { throw new ArgumentNullException("msg"); } return(diadocHttpApi.PostMessage(authToken, msg, operationId)); }
public async Task InjectMessageAsync() { var message = new MessageToPost() { Subject = "Testing message", From = "*****@*****.**", Text = "Hello World!" }; var request = new InjectMessageRequest() { Domain = Domain.Name, Inbox = InboxAll, Message = message }; var response = await mailinatorClient.MessagesClient.InjectMessageAsync(request); Assert.IsTrue(response != null); Assert.IsTrue(response.Status == "ok"); }
protected override void PerformRunCommand(string[] args) { var newMsg = NewMessage.ReadFromConsole(); var msg = new MessageToPost { FromBoxId = ConsoleContext.CurrentBoxId, ToBoxId = InputHelpers.AutocompleteBoxId(ConsoleContext, newMsg.ToBoxId), }; msg.DocumentAttachments.AddRange(newMsg.DocumentsToPost .Select(e => { var document = new DocumentAttachment { TypeNamedId = e.TypeNamedId, Function = e.Function, Version = e.Version, SignedContent = new SignedContent { Content = e.Content, Signature = ConsoleContext.Crypt.Sign(e.Content, ConsoleContext.CurrentCert.RawData) }, Comment = e.Comment, NeedRecipientSignature = e.NeedRecipientSignature, }; foreach (var m in e.Metadata) { document.AddMetadataItem(new MetadataItem { Key = m.Key, Value = m.Value }); } return(document); })); var messagePosted = ConsoleContext.DiadocApi.PostMessage(ConsoleContext.CurrentToken, msg, Guid.NewGuid().ToString("N")); System.Console.WriteLine("Было отправлено следующее письмо:"); messagePosted.WriteToConsole(); }
protected override void PerformRunCommand(string[] args) { var newMsg = NewMessage.ReadFromConsole(); var msg = new MessageToPost { FromBoxId = ConsoleContext.CurrentBoxId, ToBoxId = InputHelpers.AutocompleteBoxId(ConsoleContext, newMsg.ToBoxId), }; msg.NonformalizedDocuments.AddRange(newMsg.Attachments .Where(e => e.AttachmentType == AttachmentType.Nonformalized) .Select(e => new NonformalizedAttachment { FileName = e.FileName, SignedContent = new SignedContent { Content = e.Content, Signature = ConsoleContext.SignByAttorney ? null : ConsoleContext.Crypt.Sign(e.Content, ConsoleContext.CurrentCert.RawData), SignByAttorney = ConsoleContext.SignByAttorney }, Comment = e.Comment, NeedRecipientSignature = e.NeedRecipientSignature, })); msg.Invoices.AddRange(newMsg.Attachments .Where(e => e.AttachmentType == AttachmentType.Invoice) .Select(e => new XmlDocumentAttachment { SignedContent = new SignedContent { Content = e.Content, Signature = ConsoleContext.SignByAttorney ? null : ConsoleContext.Crypt.Sign(e.Content, ConsoleContext.CurrentCert.RawData), SignByAttorney = ConsoleContext.SignByAttorney, }, Comment = e.Comment, })); var messagePosted = ConsoleContext.DiadocApi.PostMessage(ConsoleContext.CurrentToken, msg); System.Console.WriteLine("Было отправлено следующее письмо:"); messagePosted.WriteToConsole(); }
public static void PostLargeNonformalized() { // Для использования Диадок требуются: // 1. крипто-API, предоставляемое операционной системой (доступно через класс WinApiCrypt) // 2. экземпляр класса DiadocApi, проксирующий работу с веб-сервисом Диадок var crypt = new WinApiCrypt(); var api = new DiadocApi( DefaultClientId, // идентификатор клиента DefaultApiUrl, // URL веб-сервиса Диадок crypt); // Можно использовать либо аутентификацию по логину/паролю, либо по сертификату var authToken = api.Authenticate(DefaultLogin, DefaultPassword); // Для отправки комплекта документов через Диадок требуется подготовить структуру MessageToPost, // которая и будет содержать отправляемый комплект документов var message = new MessageToPost { // GUID ящика отправителя FromBoxId = DefaultFromBoxId, // GUID ящика получателя ToBoxId = DefaultToBoxId }; // Читаем содержимое отправляемого файла var content = ReadFileContent(FileToSendName); // Загружаем отправляемый файл на "полку" (на сервер временного хранения файлов Диадок) var uploadedFileShelfName = api.UploadFileToShelf(authToken, content); // Для того, чтобы подписать файл, требуется сертификат var certContent = ReadFileContent(FileWithCertName); var cert = new X509Certificate2(certContent); // Подписываем содержимое файла var signature = crypt.Sign(content, cert.RawData); // Формируем структуру для представления неформализованного (с точки зрения Диадока) документа var attachment = new NonformalizedAttachment { Comment = "Комментарий к отправляемому документу", // Комментарий к отправляемому документу FileName = new FileInfo(FileToSendName).Name, // Протокол обмена с Диадок требует наличия имени файла (без пути!) NeedRecipientSignature = false, // Требуется ли подпись получателя DocumentDate = DateTime.Now.ToShortDateString(), // Дата составления документа DocumentNumber = "123", // Номер документа CustomDocumentId = "", // Строковый идентификатор документа (если требуется связать документы в пакете) SignedContent = new SignedContent { NameOnShelf = uploadedFileShelfName, // Имя файла, ранее загруженного на "полку" Signature = signature // Подпись к отправляемому содержимому } }; // Документ подготовлен к отправке. Добавляем его в отправляемое сообщение message.AddAttachment(attachment); // Отправляем подготовленный комплект документов через Диадок var response = api.PostMessage(authToken, message); // При необходимости можно обработать ответ сервера (например, можно получить // и сохранить для последующей обработки идентификатор сообщения) Console.Out.WriteLine("Message was successfully sent."); Console.Out.WriteLine("The message ID is: " + response.MessageId); }
public static void RunSample() { Console.WriteLine("Пример отправки универсального передаточного документа (УПД) в формате приказа №820"); Console.WriteLine("==================================================================================="); // Для использования API Диадока требуются: // 1. Крипто-API, предоставляемое операционной системой. Для систем на ОС Windows используйте класс WinApiCrypt. // 2. Экземпляр класса DiadocApi, проксирующий работу с Диадоком. var crypt = new WinApiCrypt(); var diadocApi = new DiadocApi( Constants.DefaultClientId, Constants.DefaultApiUrl, crypt); // Авторизуемся в Диадоке. В этом примере используем авторизацию через логин-пароль: var authToken = diadocApi.Authenticate(Constants.DefaultLogin, Constants.DefaultPassword); // Также можно использовать авторизацию по сертификату, она описана в примере Authenticate.cs // Для отправки комплекта документов требуется подготовить структуру MessageToPost, // которая и будет содержать отправляемый комплект документов. // Для начала, укажем в структуре идентификаторы отправителя и получателя: var messageToPost = new MessageToPost { FromBoxId = Constants.DefaultFromBoxId, ToBoxId = Constants.DefaultToBoxId }; // Перечислим связку идентификаторов, которая характеризует полный формализованный тип документа в Диадоке var typeNamedId = "UniversalTransferDocument"; // строковый идентификатор типа УПД var function = "СЧФ"; // функция, представляющая УПД как счёт-фактуру var version = "utd820_05_01_01_hyphen"; // версия, отвечающая за то, что документ сформирован в формате приказа №820 // Теперь создадим сам формализованный документ. // Мы должны получить xml, которая будет удовлетворять его схеме: https://www.diadoc.ru/docs/laws/mmb-7-15-820 // C# SDK Диадока позволяет интеграторам создать объект типа UniversalTransferDocumentWithHyphens, // который получается из кодогенерации упрощенной xsd-схемы титула документа: var userDataContract = BuildUserDataContract(); // Теперь средствами универсального метода генерации мы получим из упрощенного xml // уже реальный титул документа, который будет удовлетворять приказу №820: Console.WriteLine("Генерируем титул отправителя..."); var generatedTitle = diadocApi.GenerateTitleXml( authToken, Constants.DefaultFromBoxId, typeNamedId, function, version, 0, userDataContract.SerializeToXml()); Console.WriteLine("Титул отправителя был успешно сгенерирован."); // Подпишем полученный титул через WinApiCrypt нашим сертификатом: Console.WriteLine("Создаём подпись..."); var content = generatedTitle.Content; var certificate = new X509Certificate2(File.ReadAllBytes(Constants.CertificatePath)); var signature = crypt.Sign(content, certificate.RawData); // здесь лежит бинарное представление подписи к УПД Console.WriteLine("Создана подпись к документу."); // Теперь передадим в структуру информацию о файле. // Для этого воспользуемся универсальным полем DocumentAttachment — через него можно отправить любой тип. var documentAttachment = new DocumentAttachment { /* * Чтобы Диадок знал, какой тип документа вы хотите отправить, * нужно заполнить поле TypeNamedId (а также Function и Version, если у типа больше одной функции и версии). * Узнать список доступных типов можно через метод-справочник GetDocumentTypes. * * Для наших целей (УПД с функцией СЧФ в формате приказа №820) мы уже подобрали нужную комбинацию выше: */ TypeNamedId = typeNamedId, Function = function, Version = version, // Теперь передадим сам файл УПД и сформированную к нему подпись: SignedContent = new SignedContent { Content = content, Signature = signature }, Comment = "Здесь можно указать любой текстовый комментарий, который нужно оставить к документу", CustomDocumentId = "Тут можно указать любой строковый идентификатор, например, для соответствия с вашей учётной системой", /* * У каждого типа документа в Диадоке может быть свой набор метаданных. * Их нужно указывать при отправке, если они обязательны. * Узнать набор требуемых метаданных для конкретного набора (тип-функция-версия-порядковый номер титула) * можно через тот же метод-справочник GetDocumentTypes: смотрите поля MetadataItems. * * Для формализованных документов метаданные обычно достаются из xml самим Диадоком. * Если у метаданных указан Source=Xml, отдельно передавать в MessageToPost их не нужно. */ }; // Добавим информацию о документе в MessageToPost: messageToPost.DocumentAttachments.Add(documentAttachment); // Наконец отправляем подготовленный комплект документов через Диадок Console.WriteLine("Отправляем пакет из одного УПД с функцией СЧФ..."); Console.WriteLine("Из ящика: " + messageToPost.FromBoxId); Console.WriteLine("В ящик: " + messageToPost.ToBoxId); var response = diadocApi.PostMessage(authToken, messageToPost); // При необходимости можно обработать ответ сервера (например, можно получить // и сохранить для последующей обработки идентификатор сообщения) Console.WriteLine("Документ был успешно загружен."); Console.WriteLine("MessageID: " + response.MessageId); Console.WriteLine("Количество сущностей в сообщении: " + response.Entities.Count); // В ответе будет две сущности, т.к. контент и подпись к нему хранятся отдельно друг от друга. // Выведем информацию о самом документе. Это можно сделать так: var responseDocument = response.Entities.FirstOrDefault(e => string.IsNullOrEmpty(e.ParentEntityId)); // т.к. у документа нет "родительских сущностей" Console.WriteLine("Идентификатор документа: " + responseDocument.EntityId); Console.WriteLine("Название документа: " + responseDocument.DocumentInfo.Title); }
public static void RunSample() { Console.WriteLine("Пример отправки неформализованного документа"); Console.WriteLine("============================================"); // Для использования API Диадока требуются: // 1. Крипто-API, предоставляемое операционной системой. Для систем на ОС Windows используйте класс WinApiCrypt. // 2. Экземпляр класса DiadocApi, проксирующий работу с Диадоком. var crypt = new WinApiCrypt(); var diadocApi = new DiadocApi( Constants.DefaultClientId, Constants.DefaultApiUrl, crypt); // Авторизуемся в Диадоке. В этом примере используем авторизацию через логин-пароль: var authToken = diadocApi.Authenticate(Constants.DefaultLogin, Constants.DefaultPassword); // Также можно использовать авторизацию по сертификату, она описана в примере Authenticate.cs // Для отправки комплекта документов требуется подготовить структуру MessageToPost, // которая и будет содержать отправляемый комплект документов. // Для начала, укажем в структуре идентификаторы отправителя и получателя: var messageToPost = new MessageToPost { FromBoxId = Constants.DefaultFromBoxId, ToBoxId = Constants.DefaultToBoxId }; // Подготовим контент и подпишем его через WinApiCrypt нашим сертификатом: var content = File.ReadAllBytes(NonformalizedDocumentPath); // здесь лежит бинарное представление неформализованного документа Console.WriteLine("Создаём подпись..."); var certificate = new X509Certificate2(File.ReadAllBytes(Constants.CertificatePath)); var signature = crypt.Sign(content, certificate.RawData); // здесь лежит бинарное представление подписи к документу Console.WriteLine("Создана подпись к документу."); // Теперь передадим в структуру информацию о файле. // Для этого воспользуемся универсальным полем DocumentAttachment — через него можно отправить любой тип. var documentAttachment = new DocumentAttachment { /* * Чтобы Диадок знал, какой тип документа вы хотите отправить, * нужно заполнить поле TypeNamedId (а также Function и Version, если у типа больше одной функции и версии). * Узнать список доступных типов можно через метод-справочник GetDocumentTypes. */ TypeNamedId = "nonformalized", // Теперь передадим сам файл неформализованного документа и сформированную к нему подпись: SignedContent = new SignedContent { Content = content, Signature = signature }, Comment = "Здесь можно указать любой текстовый комментарий, который нужно оставить к документу", CustomDocumentId = "Тут можно указать любой строковый идентификатор, например, для соответствия с вашей учётной системой", /* * У каждого типа документа в Диадоке может быть свой набор метаданных. * Их нужно указывать при отправке, если они обязательны. * Узнать набор требуемых метаданных для конкретного набора (тип-функция-версия-порядковый номер титула) * можно через тот же метод-справочник GetDocumentTypes: смотрите поля MetadataItems. * * Для нашего случая, связки nonformalized-default-v1, часть ответа метода GetDocumentTypes выглядит так: * * "MetadataItems": [ * { * "Id": "FileName", * "Type": "String", * "IsRequired": true, * "Source": "User" * }, * { * "Id": "DocumentNumber", * "Type": "String", * "IsRequired": false, * "Source": "User" * }, * { * "Id": "DocumentDate", * "Type": "Date", * "IsRequired": false, * "Source": "User" * } * ] * * Это нужно читать так: для отправки неформализованного документа * обязательно нужно указывать только те метаданные, у которых IsRequired=true, * а источник: User. Под условие подходит только FileName — имя файла документа. * * Другие метаданные (DocumentNumber — номер документа, DocumentDate — дата документа) необязательны к заполнению, * но их можно указать, и тогда Диадок будет возвращать их при запросе документа, * будет отображать в веб-интерфейсе и т.п. */ Metadata = { new MetadataItem { Key = "FileName", // Из эстетических соображений можно обрезать расширение файла, но это необязательно. // Указанное здесь значение будет влиять на то, как неформализованный документ будет называться в Диадоке. // Оно может отличаться от реального названия файла. Value = Path.GetFileNameWithoutExtension(NonformalizedDocumentPath) } } }; // Добавим информацию о документе в MessageToPost: messageToPost.DocumentAttachments.Add(documentAttachment); // Наконец отправляем подготовленный комплект документов через Диадок Console.WriteLine("Отправляем пакет из одного неформализованного документа..."); Console.WriteLine("Из ящика: " + messageToPost.FromBoxId); Console.WriteLine("В ящик: " + messageToPost.ToBoxId); var response = diadocApi.PostMessage(authToken, messageToPost); // При необходимости можно обработать ответ сервера (например, можно получить // и сохранить для последующей обработки идентификатор сообщения) Console.WriteLine("Документ был успешно загружен."); Console.WriteLine("MessageID: " + response.MessageId); Console.WriteLine("Количество сущностей в сообщении: " + response.Entities.Count); // В ответе будет две сущности, т.к. контент и подпись к нему хранятся отдельно друг от друга. // Выведем информацию о самом документе. Это можно сделать так: var responseDocument = response.Entities.FirstOrDefault(e => string.IsNullOrEmpty(e.ParentEntityId)); // т.к. у документа нет "родительских сущностей" Console.WriteLine("Идентификатор документа: " + responseDocument.EntityId); Console.WriteLine("Название документа: " + responseDocument.DocumentInfo.Title); }
public Message PostMessage(string authToken, MessageToPost msg, string operationId = null) { var queryString = string.Format("/V3/PostMessage?operationId={0}", operationId); return(PerformHttpRequest <MessageToPost, Message>(authToken, queryString, msg)); }
public void Execute(ISession session) { api = new DiadocApi(/*ConfigurationManager.AppSettings["DiadokApi"]*/ "Analit-988b9e85-1b8e-40a9-b6bd-543790d0a7ec", "https://diadoc-api.kontur.ru", new WinApiCrypt()); token = api.Authenticate(ddkConfig.sender_login, ddkConfig.sender_passwd); box = api.GetMyOrganizations(token).Organizations[0].Boxes[0]; signers = new List <Signer>(); var msgs = GetMessages(); for (int i = 0; i < msgs.Item1.Count(); i++) { api.Delete(token, box.BoxId, msgs.Item2[i].MessageId, msgs.Item1[i].EntityId); } var msg = new MessageToPost(); NonformalizedAttachment nfa = new NonformalizedAttachment(); nfa.SignedContent = new SignedContent(); nfa.SignedContent.Content = Encoding.GetEncoding(1251).GetBytes("ТЕСТОВЫЙ НЕФОРМАЛИЗИРОВННЫЙ ДОКУМЕНТ"); nfa.SignedContent.SignWithTestSignature = true; nfa.FileName = "НеформализированныйДокумент.txt"; nfa.NeedRecipientSignature = true; nfa.DocumentDate = DateTime.UtcNow.ToString("dd.MM.yyyy"); nfa.DocumentNumber = DateTime.UtcNow.Millisecond.ToString(); msg.NonformalizedDocuments.Add(nfa); msg.NonformalizedDocuments.Add(nfa); msg.NonformalizedDocuments.Add(nfa); msg.NonformalizedDocuments.Add(nfa); msg.NonformalizedDocuments.Add(nfa); msg.NonformalizedDocuments.Add(nfa); msg.NonformalizedDocuments.Add(nfa); XmlDocumentAttachment sii = new XmlDocumentAttachment(); byte[] content = Encoding.GetEncoding(1251).GetBytes(DiadokFixtureData.InvoiceXml); byte[] sign = null; InvoiceInfo ii = api.ParseInvoiceXml(content); signers.Add(ii.Signer); GeneratedFile iiFile = api.GenerateInvoiceXml(token, ii); sii.SignedContent = new SignedContent(); sii.SignedContent.SignWithTestSignature = true; sii.SignedContent.Content = iiFile.Content; sii.SignedContent.Signature = sign; msg.Invoices.Add(sii); msg.Invoices.Add(sii); msg.Invoices.Add(sii); msg.Invoices.Add(sii); msg.Invoices.Add(sii); msg.Invoices.Add(sii); msg.Invoices.Add(sii); msg.Invoices.Add(sii); XmlDocumentAttachment att12 = new XmlDocumentAttachment(); content = Encoding.GetEncoding(1251).GetBytes(DiadokFixtureData.Torg12Xml); Torg12SellerTitleInfo tsti12 = api.ParseTorg12SellerTitleXml(content); signers.Add(tsti12.Signer); iiFile = api.GenerateTorg12XmlForSeller(token, tsti12, true); att12.SignedContent = new SignedContent(); att12.SignedContent.SignWithTestSignature = true; att12.SignedContent.Content = iiFile.Content; att12.SignedContent.Signature = sign; msg.AddXmlTorg12SellerTitle(att12); msg.AddXmlTorg12SellerTitle(att12); msg.AddXmlTorg12SellerTitle(att12); msg.AddXmlTorg12SellerTitle(att12); msg.AddXmlTorg12SellerTitle(att12); msg.AddXmlTorg12SellerTitle(att12); msg.AddXmlTorg12SellerTitle(att12); msg.AddXmlTorg12SellerTitle(att12); msg.FromBoxId = ddkConfig.sender_boxid; msg.ToBoxId = ddkConfig.reciever_boxid; // пакет из трех api.PostMessage(token, msg); Thread.Sleep(TimeSpan.FromSeconds(3)); msg.NonformalizedDocuments.Clear(); msg.Invoices.Clear(); msg.XmlTorg12SellerTitles.Clear(); // инвойс msg.Invoices.Add(sii); api.PostMessage(token, msg); Thread.Sleep(TimeSpan.FromSeconds(3)); msg.Invoices.Clear(); msg.XmlTorg12SellerTitles.Clear(); // накладная msg.AddXmlTorg12SellerTitle(att12); api.PostMessage(token, msg); }
public static void RunSample() { Console.WriteLine("Пример отправки документа через Полку."); Console.WriteLine("Актуально для тяжеловесных файлов (больше мегабайта)"); Console.WriteLine("===================================================="); // Для использования API Диадока требуются: // 1. Крипто-API, предоставляемое операционной системой. Для систем на ОС Windows используйте класс WinApiCrypt. // 2. Экземпляр класса DiadocApi, проксирующий работу с Диадоком. var crypt = new WinApiCrypt(); var diadocApi = new DiadocApi( Constants.DefaultClientId, Constants.DefaultApiUrl, crypt); // Авторизуемся в Диадоке. В этом примере используем авторизацию через логин-пароль: var authToken = diadocApi.Authenticate(Constants.DefaultLogin, Constants.DefaultPassword); // Также можно использовать авторизацию по сертификату, она описана в примере Authenticate.cs // Для отправки комплекта документов требуется подготовить структуру MessageToPost, // которая и будет содержать отправляемый комплект документов. // Для начала, укажем в структуре идентификаторы отправителя и получателя: var messageToPost = new MessageToPost { FromBoxId = Constants.DefaultFromBoxId, ToBoxId = Constants.DefaultToBoxId }; // Отправим контент на Полку — временное хранилище для файлов, представляемое через API Диадока: var content = File.ReadAllBytes(NonformalizedDocumentPath); // здесь лежит бинарное представление неформализованного документа Console.WriteLine("Загружаем документ на Полку..."); var uploadedFileShelfName = diadocApi.UploadFileToShelf(authToken, content); Console.WriteLine("Успешно. Путь до документа на Полке: " + uploadedFileShelfName); // Подпишем контент через WinApiCrypt нашим сертификатом и тоже отправим на Полку: var certificate = new X509Certificate2(File.ReadAllBytes(Constants.CertificatePath)); Console.WriteLine("Создаём подпись..."); var signature = crypt.Sign(content, certificate.RawData); // здесь лежит бинарное представление подписи к документу Console.WriteLine("Создана подпись к документу."); Console.WriteLine("Загружаем подпись на Полку..."); var uploadedSignatureShelfName = diadocApi.UploadFileToShelf(authToken, signature); Console.WriteLine("Успешно. Путь до подписи на Полке: " + uploadedSignatureShelfName); // Теперь передадим в структуру информацию о файле. // Подробности заполнения типа и метаданных можно посмотреть в примере PostNonformalizedDocument.cs var documentAttachment = new DocumentAttachment { TypeNamedId = "nonformalized", // Здесь мы передаём не само бинарное представление, а только путь до Полки: SignedContent = new SignedContent { NameOnShelf = uploadedFileShelfName, SignatureNameOnShelf = uploadedSignatureShelfName }, Metadata = { new MetadataItem { Key = "FileName", Value = Path.GetFileNameWithoutExtension(NonformalizedDocumentPath) } } }; // Добавим информацию о документе в MessageToPost: messageToPost.DocumentAttachments.Add(documentAttachment); // Наконец отправляем подготовленный комплект документов через Диадок Console.WriteLine("Отправляем пакет из одного неформализованного документа..."); Console.WriteLine("Из ящика: " + messageToPost.FromBoxId); Console.WriteLine("В ящик: " + messageToPost.ToBoxId); var response = diadocApi.PostMessage(authToken, messageToPost); // При необходимости можно обработать ответ сервера (например, можно получить // и сохранить для последующей обработки идентификатор сообщения) Console.WriteLine("Документ был успешно загружен."); Console.WriteLine("MessageID: " + response.MessageId); Console.WriteLine("Количество сущностей в сообщении: " + response.Entities.Count); // В ответе будет две сущности, т.к. контент и подпись к нему хранятся отдельно друг от друга. // Выведем информацию о самом документе. Это можно сделать так: var responseDocument = response.Entities.FirstOrDefault(e => string.IsNullOrEmpty(e.ParentEntityId)); // т.к. у документа нет "родительских сущностей" Console.WriteLine("Идентификатор документа: " + responseDocument.EntityId); Console.WriteLine("Название документа: " + responseDocument.DocumentInfo.Title); }