Интеграция веб-ресурсов и внешних систем на базе C# (.NET) с платформой 1С:Предприятие 8.3 через стандартный REST-интерфейс OData нередко вызывает затруднения у разработчиков. Чаще всего возникают сложности при попытке создания или изменения сущностей, содержащих табличные части: сервер возвращает ошибку 500 (Internal Server Error), код ошибки 4 или ошибку 404 (Not Found). Разберем по шагам, почему возникают эти сбои и как правильно формировать запросы к 1С для гарантированной записи данных.
Проанализируем ключевые факторы, из-за которых стандартный механизм OData отказывается сохранять объекты с табличными частями:
Collection(StandardODATA...)). Генератор часто создает некорректную сериализацию данных коллекций, из-за чего строки либо отправляются пустыми, либо вызывают ошибку структуры XML/JSON.HttpWebRequest или HttpClient нельзя дописывать спецификацию протокола (например, HTTP/1.1) в строку адреса ресурса. Из-за этого веб-сервер IIS или Apache возвращает ошибку 404 (Не найден).ПередЗаписью, ПриЗаписи, ПередУдалением). Если в типовой конфигурации в коде объекта заложены клиентские контексты (НаКлиенте) или требуется передача специфических служебных структур (например, подсистемы контактной информации БСП), OData падает с ошибкой 500.m:type и тегов <d:element> для каждой строки коллекции.Наиболее надежный и производительный путь работы с 1С OData из C# — отказ от громоздких сгенерированных WCF-клиентов в пользу отправки прямых HTTP-запросов с телом в формате JSON. Это полностью исключает искажение типов данных при сериализации.
Посмотрим на пример отправки запроса методом PATCH для обновления строк табличной части справочника. В заголовке запроса обязательно указываем ?$format=json либо заголовок Accept: application/json:
PATCH http://host/base/odata/standard.odata/Catalog_Справочник1(guid'guid-объекта')?$format=json HTTP/1.1
Host: host
Content-Type: application/json;charset=utf-8
{
"odata.metadata": "http://host/base/odata/standard.odata/$metadata#Catalog_Справочник1/@Element",
"ТабличнаяЧасть1": [
{
"LineNumber": "1",
"Реквизит1": "ЗначениеРеквизита1"
},
{
"LineNumber": "2",
"Реквизит1": "ЗначениеРеквизита2"
}
]
}
Рассмотрим подробнее правила заполнения данных табличной части при работе с JSON:
LineNumber («НомерСтроки») всегда должен передаваться явно начиная с 1 без пропусков._Key, должны содержать строковый GUID существующей записи либо значение null (если реквизит допускает пустое значение). Передача пустой строки "" приведет к ошибке формата данных.POST массив табличной части передается непосредственно внутри JSON-объекта шапки.Если специфика проекта строго требует использования формата AtomPub (XML), необходимо соблюдать точную структуру схемы метаданных 1С. Внутри свойства табличной части каждый элемент должен оборачиваться в тег <d:element> с обязательным указанием точного типа строки.
Посмотрим на пример корректного XML-пакета для создания элемента справочника «Контрагенты» с заполнением табличной части «Комментарии»:
<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<category term="StandardODATA.Catalog_Контрагенты" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<id />
<title />
<content type="application/xml">
<m:properties>
<d:DeletionMark>false</d:DeletionMark>
<d:Description>ООО Торговый Дом</d:Description>
<d:Комментарии m:type="Collection(StandardODATA.Catalog_Контрагенты_Комментарии_RowType)">
<d:element m:type="StandardODATA.Catalog_Контрагенты_Комментарии_RowType">
<d:LineNumber>1</d:LineNumber>
<d:Комментарий>Первая строка таблицы</d:Комментарий>
</d:element>
<d:element m:type="StandardODATA.Catalog_Контрагенты_Комментарии_RowType">
<d:LineNumber>2</d:LineNumber>
<d:Комментарий>Вторая строка таблицы</d:Комментарий>
</d:element>
</d:Комментарии>
</m:properties>
</content>
</entry>
Разберем ситуацию, когда сетевой запрос составлен верно, но сервер 1С возвращает код 500 Internal Server Error с сообщением типа Error running processor:
ПередУдалением или ПередЗаписью) могут ошибочно обращаться к объектам интерфейса или модулям с директивами, недоступными в контексте веб-сервисов. Выполним в конфигураторе синтаксический контроль конфигурации с установленными флагами проверки для Сервера и Внешнего соединения.ЖурналРегистрации. Откроем журнал в 1С, установим отбор по пользователю OData и выясним точную строчку кода 1С, вызвавшую аварийное завершение..cfe), добавим в него собственный HTTP-сервис и реализуем компактный метод API. В коде метода объект создается программно через платформенные механизмы 1С:
НовыйПартнер = Справочники.Партнеры.СоздатьЭлемент();
ЗаполнитьЗначенияСвойств(НовыйПартнер, ПараметрыЗапроса);
// При необходимости можно отключить проверки типовой логики:
НовыйПартнер.ОбменДанными.Загрузка = Истина;
НовыйПартнер.Записать();
Такой подход сохраняет типовую конфигурацию на полной поддержке поставщика, исключает проблемы с сериализацией сложных табличных частей и обеспечивает максимальную скорость обработки онлайн-запросов с внешнего сайта.