Как правильно создавать и обновлять записи с табличными частями в 1С через интерфейс OData?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей IT и автоматизация бизнеса
← На главную

Интеграция веб-ресурсов и внешних систем на базе C# (.NET) с платформой 1С:Предприятие 8.3 через стандартный REST-интерфейс OData нередко вызывает затруднения у разработчиков. Чаще всего возникают сложности при попытке создания или изменения сущностей, содержащих табличные части: сервер возвращает ошибку 500 (Internal Server Error), код ошибки 4 или ошибку 404 (Not Found). Разберем по шагам, почему возникают эти сбои и как правильно формировать запросы к 1С для гарантированной записи данных.

Причины возникновения ошибок при работе с OData 1С

Проанализируем ключевые факторы, из-за которых стандартный механизм OData отказывается сохранять объекты с табличными частями:

  1. Некорректная генерация прокси-классов WCF / OData Client. Инструменты генерации строго типизированных клиентов в Visual Studio сопоставляют табличные части 1С как коллекции комплексных типов (Collection(StandardODATA...)). Генератор часто создает некорректную сериализацию данных коллекций, из-за чего строки либо отправляются пустыми, либо вызывают ошибку структуры XML/JSON.
  2. Ошибки в URI запроса. При ручном формировании запросов через HttpWebRequest или HttpClient нельзя дописывать спецификацию протокола (например, HTTP/1.1) в строку адреса ресурса. Из-за этого веб-сервер IIS или Apache возвращает ошибку 404 (Не найден).
  3. Срабатывание серверной бизнес-логики БСП. Стандартный сервис OData при сохранении вызывает методы модулей объектов и подписок на события (ПередЗаписью, ПриЗаписи, ПередУдалением). Если в типовой конфигурации в коде объекта заложены клиентские контексты (НаКлиенте) или требуется передача специфических служебных структур (например, подсистемы контактной информации БСП), OData падает с ошибкой 500.
  4. Специфика формата AtomPub (XML). XML-сериализация в 1С OData чрезвычайно чувствительна к пространствам имен, указанию атрибутов m:type и тегов <d:element> для каждой строки коллекции.

Решение 1. Использование прямого JSON-протокола вместо XML и WCF-прокси

Наиболее надежный и производительный путь работы с 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:

  1. Реквизит LineNumber («НомерСтроки») всегда должен передаваться явно начиная с 1 без пропусков.
  2. Все ссылочные поля табличной части, оканчивающиеся на _Key, должны содержать строковый GUID существующей записи либо значение null (если реквизит допускает пустое значение). Передача пустой строки "" приведет к ошибке формата данных.
  3. При создании нового объекта методом POST массив табличной части передается непосредственно внутри JSON-объекта шапки.

Решение 2. Корректная структура XML для создания объекта с табличной частью

Если специфика проекта строго требует использования формата 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>

Диагностика ошибки 500 и обход ограничений типовых конфигураций

Разберем ситуацию, когда сетевой запрос составлен верно, но сервер 1С возвращает код 500 Internal Server Error с сообщением типа Error running processor:

  1. Проверка серверных модулей. В типовых решениях некоторые обработчики событий (например, ПередУдалением или ПередЗаписью) могут ошибочно обращаться к объектам интерфейса или модулям с директивами, недоступными в контексте веб-сервисов. Выполним в конфигураторе синтаксический контроль конфигурации с установленными флагами проверки для Сервера и Внешнего соединения.
  2. Анализ Журнала регистрации. При возникновении ошибки 500 платформа записывает полный стек исключения в ЖурналРегистрации. Откроем журнал в 1С, установим отбор по пользователю OData и выясним точную строчку кода 1С, вызвавшую аварийное завершение.
  3. Использование расширений конфигурации (без снятия с поддержки). Если типовой объект перегружен проверками БСП (например, сложная валидация контактной информации у партнеров), стандартный OData не позволит обойти эти правила. В этом случае создадим собственное Расширение конфигурации (файл .cfe), добавим в него собственный HTTP-сервис и реализуем компактный метод API. В коде метода объект создается программно через платформенные механизмы 1С:

НовыйПартнер = Справочники.Партнеры.СоздатьЭлемент();
ЗаполнитьЗначенияСвойств(НовыйПартнер, ПараметрыЗапроса);
// При необходимости можно отключить проверки типовой логики:
НовыйПартнер.ОбменДанными.Загрузка = Истина;
НовыйПартнер.Записать();

Такой подход сохраняет типовую конфигурацию на полной поддержке поставщика, исключает проблемы с сериализацией сложных табличных частей и обеспечивает максимальную скорость обработки онлайн-запросов с внешнего сайта.

← На главную