При интеграции 1С с внешними веб-сервисами (особенно разработанными на платформе Microsoft .NET / WCF / ASMX) разработчики часто сталкиваются с передачей параметров типа guid. Попытка передать строковый идентификатор напрямую может приводить к ошибке валидации XDTO. Разберем подробнее, почему возникает эта ошибка и как правильно подготовить и передать значение GUID.
Рассмотрим типовую ситуацию. При попытке заполнить свойство объекта XDTO строковым значением идентификатора возникает исключение:
Ошибка при установке значения атрибута контекста (consumerId)
по причине:
Несоответствие типов XDTO
по причине:
Ошибка проверки данных XDTO:
Значение: '{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}' не соответствует простому типу: {http://microsoft.com/wsdl/types/}guid Значение не соответствует образцу
Выясним причину такого поведения платформы. В WSDL-описании сервиса тип guid из пространства имен http://microsoft.com/wsdl/types/ описывается ограничением стандартного строкового типа с помощью регулярного выражения:
<xs:simpleType name="guid">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"/>
</xs:restriction>
</xs:simpleType>
Обратим внимание на шаблон xs:pattern: он строго ожидает 32 шестнадцатеричные цифры, разделенные четырьмя дефисами (формат 8-4-4-4-12). Любые обрамляющие фигурные скобки {} или пробелы приводят к нарушению шаблона, из-за чего механизм XDTO в 1С выбрасывает исключение валидации еще до отправки SOAP-пакета в сеть.
Если строковое значение GUID получено из внешнего источника (из почты, реестра, базы данных или COM-объекта), оно нередко содержит фигурные скобки. Избавимся от них перед присвоением свойству XDTO.
Разберем пошаговый пример создания параметров и обращения к веб-сервису через WSПрокси:
// Создаем прокси для веб-сервиса
Прокси = WSСсылки.ИмяWSСсылки.СоздатьWSПрокси("http://tempuri.org/", "Catalog", "CatalogSoap");
// Получаем тип параметра операции из пакета XDTO
ТипWSПараметра = Прокси.ФабрикаXDTO.Пакеты.Получить("http://tempuri.org/").Получить("SearchParts");
WSПараметр = Прокси.ФабрикаXDTO.Создать(ТипWSПараметра);
// Исходный идентификатор со скобками
ИдентификаторСтрокой = "{11111111-1111-1111-1111-111111111111}";
// Удаляем фигурные скобки
ЧистыйGUID = СтрЗаменить(СтрЗаменить(ИдентификаторСтрокой, "{", ""), "}", "");
// Присваиваем корректную строку без скобок
WSПараметр.consumerId = ЧистыйGUID;
// Выполняем вызов операции
Результат = Прокси.SearchParts(WSПараметр);
Если в конфигурации 1С идентификатор хранится в виде ссылки на объект или как встроенный тип УникальныйИдентификатор, достаточно преобразовать его в строку с помощью функции Строка() или XMLСтрока(). Платформа 1С автоматически сформирует строку без фигурных скобок.
Посмотрим на пример:
// Получаем уникальный идентификатор ссылки 1С
Идентификатор1С = СсылкаНаОбъект.УникальныйИдентификатор();
// Преобразование возвращает строку вида "11111111-1111-1111-1111-111111111111"
СтроковыйGUID = Строка(Идентификатор1С);
WSПараметр.consumerId = СтроковыйGUID;
В некоторых случаях, когда требуется строгий контроль типов или передача значения в универсальные контейнеры anyType, полезно явно инициализировать объект типа через ФабрикаXDTO.
Разберем, как это реализовать:
// Получаем тип guid из пространства имен WSDL
ТипGUID = Прокси.ФабрикаXDTO.Тип("http://microsoft.com/wsdl/types/", "guid");
// Создаем типизированное значение XDTO
ЗначениеGUID = Прокси.ФабрикаXDTO.Создать(ТипGUID, "11111111-1111-1111-1111-111111111111");
WSПараметр.consumerId = ЗначениеGUID;
"", так как она не пройдет проверку регулярным выражением. В этом случае передают нулевой GUID: "00000000-0000-0000-0000-000000000000".[0-9a-fA-F], сторонние веб-сервисы на платформе Linux или в строгих сериализаторах могут требовать нижний регистр. Для надежности можно использовать функцию НРег(СтроковыйGUID).Прокси.ИмяОперации(ЧистыйGUID). 1С автоматически сериализует корректную строку в нужный тип схемы.