Доброго всем дня!
Завис с вопросом наглухо. Делаю интеграцию для корпоративных закупок в с ЭТП ГПБ.
От ЭТП получаю схему WSDL и по ней собираю тело запроса. В описании к запросу от ЭТП некоторые даты должны иметь формат с таймзоной.
формат : dateTime(\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\+\d\d:\d\d) или вот так то же самое: строгий формат Y-m-d\TH:i:sP (пример "2018-11-28T14:00:07+03:00" )
В итоге, формирую структуру тела, присваиваю в установленном формате дату и, ... Таимзона исчезает.
Пробовал и так:
BaseAnnouncement.date_start_registration = XMLСтрока(НачалоДня(ДатаНачПриема) + 32400) + "+03:00"; //Начало приема заявок
Всё одинаково, справа от равно таймзона есть, слева она теряется. От этп ошибка приходит, формат не соответствует.
В SoapUI руками таймзону прописываю и всё без ошибок проходит и закупочная процедура создается на ЭТП. Там строка вот так выглядит:
Где я не так копаю? Кто может помочь?
Ещё может заодно по префиксам кто поможет? Из полученной от ЭТП схемы в SoapUI префиксы получаются как надо - ns. А в 1С у меня при формировании на выходе префиксы вот такие: d2p...
Пока временно решил эту проблему просто заменой текста, Сформированный ОбъектXDTO конвертирую в XML и заменяю в тексте поиском. Потом обратно конвертирую в ОбъектXDTO и отправляю запрос. Костыль, но пока так вот.
Вопрос с датой уже горит....!
(2)Ссылку думаю ничего страшного дать нет, но всё же у них получу разрешение для порядка.
Сходу не вижу как картинку вставить... только через сервисы кнопка... прикреплю файлом.
Пока на скрине видно тип даты в полученной схеме какой и у него там формат как оговорено: \d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\+\d\d:\d\d
Думал извернутся и конвертнул сформированный ОбъектXDTO в XML поправил и обратно в ОбъектXDTO, но уже без привязки к полученной схеме, к ней не дает, ругается на несоответствия этих значений... Не прошло... И с префиксами так же думал проскочить, тоже не пошло...
(2)после описанной выше конвертации и получается не дата там, а строка в этих полях дат. В ответ падает ошибка от запрашиваемого сервиса: При вызове веб-сервиса произошла ошибка. Ошибка SOAP сервера: Call to undefined method stdClass::getItemData()
(4)По поводу даты - тоже не получилось, при присваивании просто изменяется дата на смещение часового пояса.
А по поводу пространства имен - так то без разницы какой будет префикс - ns, abs или любой другой.
Файл будет корректен, с точки зрения xml.
(9)На скрине выше - формат в схеме желтым выделил, там с Временной зоной на конце.
И на ИТС тоже она написана параметр такой есть, но не обязательный.
https://its.1c.ru/db/metod8dev/content/1793/hdoc
(9)Примерно так и поступал. Конвертировал собранную ХДТО и от схемы отвязывался. Там всё в стринг конвертируется после этого. Ну вложенные ХДТО структуру сохраняют, но все поля тип Стринг становятся.
Функция УбратьЛишнее(СтрокаXMLТело); скопипастина с инфостарта, добавил строку по замене префикса только
Функция УбратьЛишнее(xml)
xml = СтрЗаменить(xml,"xsi:type=""xs:decimal""", "");
xml = СтрЗаменить(xml,"xsi:type=""xs:string""", "");
xml = СтрЗаменить(xml,"xsi:type=""xs:boolean""", "");
xml = СтрЗаменить(xml,"xsi:type=""xs:dateTime""", "");
xml = СтрЗаменить(xml,"T00:00:00", "");
xml = СтрЗаменить(xml,"0001-01-01", "");
xml = СтрЗаменить(xml,"<Value ", "<Vl");
xml = СтрЗаменить(xml,"", "");
xml = СтрЗаменить(xml,"false", "0");
xml = СтрЗаменить(xml,"true", "1");
xml = СтрЗаменить(xml,"xsi:type=""Null""", "");
//Для красоты 1С рисует структуру при помощи табуляции, это удобно читать, то для парсинга – это мусор, поэтому мы убираем все лишние табуляции, что позволяет сократить объем данных в 2 раза
xml = СтрЗаменить(xml," ","");
xml = СтрЗаменить(xml,"d2p","ns");
Возврат xml
КонецФункции
(15)Все равно не понимаю, в чем смысл замены пространства имен в xml, ведь при чтении его в XDTO, оно же все равно теряется все. Разве нет?
При вызове метода WS XDTO ведь обратно в xml преобразуется.
(16)Честно говоря не так часто делаю вебсервисы, что бы так в тонкостях совсем на "ТЫ" быть... последний раз года 4 назад делал уже и там я отвечал на приходящие запросы от разных источников. НТТР недавно делал обмены, но там с этим проще в разы, ни разу не трогая разобрался быстро. А тут,... вроде бы почти всё готово уже, но из за префикса и этих вот дат, при чем не во всех полях, только 4 даты ругаются на формат, встрял...
(16)Так, по префиксам. Сейчас вернулся к стоковому запросу с префиксом d2p и запрос прошел. Получил в ответе ошибку по этим 4 полям с датами. Не верный формат даты...
Похоже решения как такового получая схему от ЭТП динамически нет. Нужно будет WSСсылку создавать, в ней изменить нужные даты на тип Сринг и так формировать.
ЭТП предлагают весь XML собирать руками только.
Так что вопрос скорее закрыт видимо.
(21)
(21)Добрый день!
Тогда ни как не смог используя WSDL ссылку для составления запроса.
Выход только руками собирать XML запрос, не используя объектную модель и вставлять в тело собранную её в сообщение.
Поддержка ЭТП ГПБ согласилась с багом, но исправить может позже обещали. А позже я уже этот вопрос не касался.
Пока не исправили и вряд ли исправят. Cобрать вручную через запись XML - это мне понятно и по силам. А как передать XML? Через WSПрокси - не получиться, какой вариант передачи использовать? Можешь подсказать? А лучше кинь пример. Пожалуйста.
(23)
(23)
Из другой задачи пример сейчас могу показать. /Это я интеграцию бухни с налоговым мониторингом делал. Тут нужно заголовки будет ещё прописывать, они в пользовательском режиме задаются в справочнике настроек, но в приведенном коде оставлены примеры для отладки.
Функция _Веб_Сервис_Данные_Отправить( пПараметры ) Экспорт
лДанные = пПараметры._Данные;
лРезультат = Новый Структура( "_Дата_Отправки, _Ошибка_Описание, _Состояние" );
лHTTP_Запрос = Новый HTTPЗапрос( пПараметры._Сервер_Ресурс );
//лHTTP_Запрос.Заголовки.Вставить( "Content-Length",СтрДлина(лДанные)); // тестово заголовок
Если ТипЗнч( пПараметры._Заголовки ) = Тип( "Соответствие" ) Тогда
Для Каждого лЭлемент Из пПараметры._Заголовки Цикл
//!!!!! вычисляемый заголовок, сделать через спец. теги
//лHTTP_Запрос.Заголовки.Вставить( "Content-Type", "multipart/related;type=""text/xml"";boundary=""" + пПараметры._Данные_Блоки_Разделитель + """" );
//лHTTP_Запрос.Заголовки.Вставить( "Content-Type", "multipart/related;type=""text/xml"";boundary=""" + _Boundary() + """" );
лHTTP_Запрос.Заголовки.Вставить( лЭлемент.Ключ, лЭлемент.Значение );
КонецЦикла;
КонецЕсли;
Если ТипЗнч( лДанные ) = Тип( "ДвоичныеДанные" ) Тогда
//лHTTP_Запрос.Заголовки.Вставить( "Content-Type", "multipart/related;type=""text/xml"";boundary=""" + _Boundary() + """" );
лHTTP_Запрос.Заголовки.Вставить( "Content-Type", "Multipart/Related; type=""application/xop+xml"";boundary=""" + _Boundary() + """" );
лHTTP_Запрос.УстановитьТелоИзДвоичныхДанных( лДанные );
Иначе
//лHTTP_Запрос.Заголовки.Вставить( "Content-Length",СтрДлина(лДанные)); // тестово заголовок (1С не умеет корректно высчитывать длину сообщения)
лHTTP_Запрос.УстановитьТелоИзСтроки( лДанные, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать );
КонецЕсли;
Если пПараметры._Защищенное_Соединение = Истина Тогда
//лЗащищенное_Соединение = Новый ЗащищенноеСоединениеOpenSSL( , Новый СертификатыУдостоверяющихЦентровОС );
лЗащищенное_Соединение = Новый ЗащищенноеСоединениеOpenSSL;
Иначе
лЗащищенное_Соединение = Неопределено;
КонецЕсли;
лПрокси_Сервер = Новый ИнтернетПрокси( Истина );
лHTTP_Соединение = Новый HTTPСоединение( пПараметры._Сервер_Имя, пПараметры._Порт, пПараметры._Пользователь, пПараметры._Пароль, лПрокси_Сервер, пПараметры._Таймаут, лЗащищенное_Соединение, Ложь );
лРезультат._Дата_Отправки = ТекущаяДата();
Попытка
Если пПараметры._HTTP_Запрос_Метод = Перечисления.НМ_HTTP_Запрос_Методы._POST Тогда
лHTTP_Ответ = лHTTP_Соединение.ОтправитьДляОбработки( лHTTP_Запрос );
ИначеЕсли пПараметры._HTTP_Запрос_Метод = Перечисления.НМ_HTTP_Запрос_Методы._GET Тогда
лHTTP_Ответ = лHTTP_Соединение.Получить( лHTTP_Запрос );
ИначеЕсли пПараметры._HTTP_Запрос_Метод = Перечисления.НМ_HTTP_Запрос_Методы._PATCH Тогда
лHTTP_Ответ = лHTTP_Соединение.Изменить( лHTTP_Запрос );
ИначеЕсли пПараметры._HTTP_Запрос_Метод = Перечисления.НМ_HTTP_Запрос_Методы._HEAD Тогда
лHTTP_Ответ = лHTTP_Соединение.ПолучитьЗаголовки( лHTTP_Запрос );
ИначеЕсли пПараметры._HTTP_Запрос_Метод = Перечисления.НМ_HTTP_Запрос_Методы._PUT Тогда
лHTTP_Ответ = лHTTP_Соединение.Записать( лHTTP_Запрос );
ИначеЕсли пПараметры._HTTP_Запрос_Метод = Перечисления.НМ_HTTP_Запрос_Методы._DELETE Тогда
лHTTP_Ответ = лHTTP_Соединение.Удалить( лHTTP_Запрос );
Иначе
лHTTP_Ответ = лHTTP_Соединение.ОтправитьДляОбработки( лHTTP_Запрос );
КонецЕсли;
Если лHTTP_Ответ.КодСостояния = 200 Тогда
лРезультат._Состояние = Перечисления.НМ_СтатусОтправленногоБлока_ИУС_НК.БлокДанныхОтправлен;
Иначе
лРезультат._Состояние = Перечисления.НМ_СтатусОтправленногоБлока_ИУС_НК.ОшибкаОтправки;
лРезультат._Ошибка_Описание = "Код состояния: " + лHTTP_Ответ.КодСостояния + Символы.ПС + Символы.ПС + лHTTP_Ответ.ПолучитьТелоКакСтроку();
КонецЕсли;
Исключение
лРезультат._Состояние = Неопределено;
Перечисления.НМ_СтатусОтправленногоБлока_ИУС_НК.ОшибкаОтправки;
лРезультат._Ошибка_Описание = "" + ТекущаяДата() + ": " + ИнформацияОбОшибке().Описание + ?( ТипЗнч( ИнформацияОбОшибке().Причина ) = Тип("ИнформацияОбОшибке"), ": " + ИнформацияОбОшибке().Причина.Описание, "" )
+ "; Сервер: " + пПараметры._Сервер_Имя + "; Ресурс: " + пПараметры._Сервер_Ресурс + "; Порт: " + пПараметры._Порт + "; Пользователь: " + пПараметры._Пользователь + ";";
КонецПопытки;
Возврат лРезультат;
КонецФункции
(24) Ещё на всякий случай. Тут в коде прикрепление двоичных данных, но там в формате МТОМ идет присоединение файлов. Так, для информации ещё на всякий случай, что тут не в base64, и с такой XML там и свои заголовки идут.
(23)
А, ещё вроде помнится момент с заголовками. Там 1С не умеет правильно длину определять и заголовок это вот приводил к ошибке вроде, но это не точно... уже не помню.
(22) И сейчас перечитал свой пост выше и вспомнил что в итоге я сделал, там выше это и написано было уже.
Тогда я получил от них файл с описанием WSDL. В нем заменил тип дата на строка в нужных полях и просто как строку с временной зоной туда текст вставил и заработало. 3 года прошло, уже позабылось малость)))
А у себя обращение не к их WSDL сделал, а в совей конфигурации сохранил полученную с изменениями своими и уже к ней обращался.
Недостаток явный в том, что при изменении у них чего-то в WSDL - надо запрашивать снова от них свежую и снова править и подгружать в свою конфу.