Обязательное возвращаемое значение не задано 1с веб сервис
Некоторые из вас наверное знают, что на платформе 1C:Enterprise 8 (1С: Предприятие 8) некоторые безумцы умельцы, помимо приложений для бухгалтеров, делают, например еще и игры. Но речь пойдет не о разработке игр, хотя в какой-то мере веб-сервисы можно использовать и для этого.
Хотя платформа 1C:Enterprise 8 и предметно ориентирована, но благодаря наличию в ней технологий COM, OLE, XML, HTML, SOAP и некоторых других, может использоваться и для задач не связанных напрямую с автоматизацией бизнеса. Лично меня в ней привлекает очень быстрая скорость разработки, отладки и разворачивания приложения. Эти характеристики для меня являются ключевыми при выборе платформы для прототипирования.
Под катом я на простом примере покажу насколько быстро на платформе 1C:Enterprise 8 можно реализовать веб-сервис, разработать для него базу данных и опубликовать на веб-сервере. Приведенный пример, в немного измененном виде, используется в большом и реальном проекте, прототип которого было решено реализовать на 1C. Проект еще находится в стадии разработки, но я все больше склоняюсь к тому, чтобы и финальную реализацию сделать на этой платформе.
Постановка задачи примера
Специально для ненавистников кириллицы весь код (и наименование платформы) представлен в англоязычном написании.
Разработка базы данных
Надеюсь добавить новое приложение для разработки на платформе 1С не вызовет ни у кого каких бы то ни было затруднений. В общих чертах при добавлении (1) необходимо указать его наименование и место расположения. Для непосредственной разработки приложения необходимо перейти в режим Designer (2).
Нам понадобится всего пара кликов, чтобы создать хранилище файлов в базе данных. Для этого добавляем в приложение catalog (справочник) FileStorage.
Определяем для него один единственный реквизит ValueStorage с типом ХранилищеЗначения.
Всё, структура базы данных для хранения файлов реализована. Мы будем хранить только двоичные данные самого файла, имя хранить для нашего примера не нужно. Если все-таки понадобится, то решается это также достаточно просто – добавляем еще один реквизит для хранения наименования файла.
Реализация веб-сервиса
Теперь приступим к разработке самого веб-сервиса.
Добавим новый веб-сервис в приложение. Зададим ему имя FileStorageService.
Обязательно определим для него пространство имен.
И добавим два метода PutFile(File тип base64binary) возвращаемое значение типа string и GetFile(Id тип string) возвращаемое значение типа base64binary. В модуле веб-сервиса напишем для них несколько строчек кода:
If File.Size() = 0 Then
Raise "INVALID_BINARY_DATA";
EndIf;
// Добавление файла в БД.
NewFile = Catalogs.FileStorage.CreateItem();
NewFile.ValueStorage = New ValueStorage(File);
NewFile.Write();
// Поиск файла в БД по переданному коду.
File = Catalogs.FileStorage.FindByCode(Number(Id));
If NOT ValueIsFilled(File) Then
Raise "INVALID_FILE_CODE";
EndIf;
Публикация на веб-сервере
Далее назначим эту роль первому созданному пользователю (Administration -> Users -> Add) – администратору.
После этого в список добавим обычных пользователей.
После добавления пользователей опубликуем наш веб-сервис. Публикация (Administration -> Publishing on web-server. ) возможна на IIS или Apache. Все необходимые для этого действия платформа выполняет автоматически. Нам необходимо только нажать кнопку Publish.
Это всё, опубликованным веб-сервисом можно уже пользоваться.
Как мне кажется прочтение этого текста займет гораздо больше времени, чем заняла реализация. Надеюсь уважаемым хабралюдям было интересно узнать, что прототипировать веб-сервисы на платформе 1C:Enterprise 8 достаточно быстро и просто. В некоторых средах разработки обычный «Hello world» реализовать гораздо сложнее.
Соединение и выполнение некоторых API команд происходит успешно, если в параметрах команд простые типы (Число, Дата, Булево), а если в параметрах необходимо передать Массив, или структуру то вызов не проходит.
Скорей всего необходимо Объект 1с (Массив, Структуру и т.п.) перевести в Тип который ожидает сервис.
ОбъектXDTO = Сериализатор.ЗаписатьXDTO(Новый Массив());
Ответ=Client.getCurrencyList("demo_api", "demo@example.com", "demo",ОбъектXDTO);
в первых 3 параметрах указывается информация аутентификации, а в 4 параметр надо для этой функции передать пустой массив.
При этом при вызове функции выдается ошибка
"Ошибка установки соответствия префикса и URI пространства имен"
Видимо надо каким то образом указать, что мой массив принадлежит тому пространству имен который ожидает сервис. Не пойму как это сделать
Подключение к веб сервису:
ОпределениеТ=Новый WSОпределения("http://www.drebedengi.ru/soap/dd.wsdl");
WSСервис=ОпределениеТ.Сервисы[0];
Client=Новый WSПрокси(ОпределениеТ, WSСервис.URIПространстваИмен, WSСервис.Имя, WSСервис.ТочкиПодключения[0].Имя);
За ранее хочу сказать, что с XDTO и сервисами только пытаюсь, что то делать, поэтому возможно неправильно использую термнилагию.
только один пакет "http://www.w3.org/2001/XMLSchema"
Пробовал написать вот так:
ПространствоИмен="http://www.w3.org/2001/XMLSchema";
Связывался с разработчиком, он говорит что этот параметр должен быть пустой, он служебный и заполнять его не надо.
Но при этом он ругается, что параметр не заполнен при вызове из 1с.
(6) 2 элемента ситуацию не спасло. все равно пишет
"Ошибка SOAP сервера: getCurrencyList: Parameter 'idList' must be an array"
попробовал записать этот объект в хмл вот такой код:
(9)
Первый вариант
"Ошибка при вызове метода объекта модели XDTO.
Второй вариант:
"Обязательный параметр не задан: :ddengiService:getCurrencyList(. idList. )"
Он посоветовал, поставить php там есть рабочий пример на пхп.
Пошел, ставить, поидее там же и будет видно какой должен быть XML запрос.
можешь сохранить в файл и дописать ипорт
смотри v8: Заполнение массива XDTO
82
targetNamespace="http://xml.apache.org/xml-soap"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
(16) Сохранил в файл, что ты указал. Далее в конфу в пакеты XDTO загрузил эту схему далее:
Ошибка:
как выглядит MAP в ХМЛ:
Что касается (14) (15) не совсем понял как импортировать это, поидее (16) уже готовый тип.
(18) Сохранил wsdl далее в какое место файла необходимо вставить:
Выдается ошибка при выполнении:
"Фатальная ошибка:
Extra content at the end of the document
Не совсем понял, для чего ты указываешь:
"Там в файле есть секция определяющая путь к первису и точки подключения"
Смотри v8: Заполнение массива XDTO
82 там после
импорт идет в секции типов Попробуй создать эту секцию со свои пространством имен
Добавил вот это:
В прокси появились доп. пакеты:
"http://schemas.xmlsoap.org/soap/encoding/"
Ошибка:
Несоответствие типов XDTO:
Тип 'Map' не найден
Тип объекта не является открытым
(29) ты указал на код "Set currency list"
поидее, это какая то запись в базу.
В параметрах надо указать "list" думаю это не тоже самое, что и "idList" в параметрах вызова операции getCurrencyList
Судя по всему Веб сервис там ожидает только числовые значения, т.к. выдается ошибка на какой то другой
Попробовал указать 0, тогда вызов проходит getCurrencyList (думал это уже не случится=)), но ответ приходит пустой.
Написал еще разработчику, может подскажет какими значениями надо заполнить параметр idList чтобы получить норм ответ.
Serginio1, а как то можно в схеме wsdl которую мы указываем, для параметра idList указать, что он не является обязательным?
Когда в конфу загружаешь по ссылке wsdl, то там у параметров показывается свойство: Возможно пустое, там оно везде Ложь
(34) Возможно ошибки были при возврате значения
v8: Заполнение массива XDTO
см 100 Там точно возвращался map а 1С не могла разобрать этот тип
(37) у меня возвращается Неопределено, и ошибки не выскакивает
Ошибка:
Ошибка разбора XML: - [79,28]
Фатальная ошибка:
Попробовал просто удалить эту строку idList, тогда параметр не требуется но при вызове функции, но сервер все равно выдает ошибку:
Т.е. это на стороне сервера.
(38) Знач проблема на сервере или что то нужно подставлять по умолчанию
minOccurs это для полей структуры. Хрень сморозил. Есть понятие возможно пустое значение, но туда передается anySimpleType
Нашел еще один варинат работы через SOAP клиент, с помощью , но результат тот же.
Ошибка:
"Произошла исключительная ситуация (Client): Client:Incorrect number of parameters supplied for SOAP request HRESULT=0x80070057: Параметр задан неверно.
- Client:Unspecified client error. HRESULT=0x80070057: Параметр задан неверно."
Уже можно указать "" в качестве параметра, но при попытке выполнить выдает:
Произошла исключительная ситуация (SoapMapper): SoapMapper:Restoring data into SoapMapper anyType failed HRESULT=0x8007000E: Недостаточно памяти для завершения операции.
- Client:Unspecified client error. HRESULT=0x8007000E: Недостаточно памяти для завершения операции.
Думал, мб с 1с что то. Сделал подключение через SoapClient с помощью AutoIT результат, тот же не удается выполнить команды.
(43) у меня что то проблемы с установкой PHP на комп, точнее с портом 80.
Пробовал Денвер, поидее ничего не надо прописывать, устанавливаешь и все.
Вообщем пока php код не могу выполнить.
Далее в коде пытаюсь выполнить:
Объект = Фабрика.Создать(Фабрика.Тип("http://www.w3.org/2001/XMLSchema-instance","nil"));
Это неопределено в отладчике.
А вот если присвоить это значение какомунибудь anyType она правильно прописывает.
"А вот если присвоить это значение какомунибудь anyType она правильно прописывает."
Возможно, но как это сделать, чтобы передать в параметр WS операции.
В XML файле получается так:
При вызове операции выдается ошибка.
Ошибка SOAP сервера: getCurrencyList: Parameter 'idList' must be an array
(69) Вообще то nillable="true" для anyType это не совсем то. Кстати, а что возвращает то сервис?
Ответ от разработчика:
"Вам нужно добиться, чтобы передаваемый XML был таким-же, как у PHP скрипта.
На самом деле не только у PHP скрипта, многие стандартные библиотеки, в частности под все мобильные устройства - тоже умеют это делать, т.к. независимые разработчики это реализовали в приложениях.
Каким должно быть значение параметра, чтобы 1с сгенерил такой XML - вам нужно разобраться."
(70) сервис вернет, поидее массив записей о движениях, вроде как.
"и что возвращает http://www.soapui.org"
Честно говоря не понял, для чего этот сервис.
"Нагрузочное тестирование веб сервисов" ?
странно, что он выдает ответ
Ошибка SOAP сервера: getCurrencyList: Parameter 'idList' must be an array
А какой эррай если передается nil?
Понимаю, что это не особо средствами 1с. Но все же, лучше чем ничего.
Огромное спасибо за помощь Serginio1
(81) А объекты ты можешь из XML ответа подгружать используя прокси фабрику.
(80) А 64 не подошел?
(86) Почему то при чтении выдает ошибку
в wsdl в шапке прописано
Стал разбираться с возможно пустой параметр. nillable в параметрах не прокатывает
в 1с для параметров городится структура г де у параметра указывается nillable например
а зачем вот это? ПараметрТип = Фабрика.Тип("http://soap.ecm.emotion.com/","GetCurrentCredit"); ты ничего больше не забыл? и это тоже непонятно
Это просто я делал много попыток, чтобы заработало, забыл убрать. ДА и объявление результата тоже не нужно, но это не влияет на результат. Просто пытался уже подходить со всех сторон.
А как обойти проблему? Интернет в офисе раздается через прокси, это да. Пробовал дома, дома прокси нет (интернет раздается через рутер), возникла та же проблема. Может тогда дело не в прокси?
Функция GetCurrentCredit имеет один параметр auth. Это структура со строчными параметрами username и password. Система не ругается на недопустимый параметр, она почему то ругается на возвращаемое значение этой функции, которое имеет тип result.
при выполнении функции сервиса, может возникать внутренняя ошибка. тут сервис в натуре пощупать надо, а доступа к нему нету
У них похоже сервак лежал. Уже есть доступ. Работал с этим сервисом через сайт - все работает. Через 1с - не хочет.
Нужна помощь, не знаю в какую сторону копать. Если это глюк 1С (несостыковка со сторонним сервисом), как реализовать работу с этим веб сервисом сторонними средствами? Главное чтобы работало все через 1С
С вебсервисом могу работать через сторонние средства, например такие как Аэрофлот проверить не могу, надо просить админа добавить мне его в разрешенный список. Даже если он заработает, что это мне даст? Может можно как то сохранить ответный XML в файл, и вручную его обрабатыватть? Или вручную формировать XML и отправлять на сервер. Только как это реализовать? Вопрос критичен, к сожалению, в пятницу уже надо сдать рабочую версию, а решения все нет :(
хм.. а у меня выдает это: Ошибка проверки данных XDTO: Структура объекта не соответствует типу: < Ошибка преобразования данных XDTO: Чтение объекта типа: < - [1,217] Проверка дополнительного свойства: форма: Элемент имя: comment Неизвестная ошибка. Ошибка преобразования данных XDTO: Чтение объекта типа: < - [1,217] Проверка дополнительного свойства: форма: Элемент имя: comment Ошибка вызова операции сервиса: < Ошибка вызова операции сервиса: < Ошибка при вызове метода контекста (GetCurrentCredit): Ошибка вызова операции сервиса:
Ну так не на него же ругается. Да и зачем в итоге серверу возвращать пустую инфу, если он просто возвращает то, что у него попросили?
Да, не на него. А то что в это именно то что возвращает сервер по твоему запросу? А тут логику искать не надо, надо просто чтобы все соответствовало схеме.
Тот сырой XML текст, что я привел, это ответ сервера на функцию GetCurrentCredit. Получено с помощью сайта, что я приводил выше.
Цель блога описать интересные и полезные примеры программирования в системе 1С:Предприятие 8.
воскресенье, 14 октября 2012 г.
1С:Предприятие 8. Веб-сервисы. Реализация веб-сервиса
После этих действий веб-сервисом можно будет пользоваться. Таким образом будет создан веб-сервис, который сможет оперировать только простыми типами данных.
Откройте конфигурацию и в дереве метаданных найдите ветку "Общие - Web-сервисы". Нажмите правой кнопкой и добавьте новый элемент.
Имя веб-сервиса можно задать русское. И платформа его сохранит и опубликует, но рекомендую использовать латиницу в названиях веб-сервисов, ws-операций, параметров ws-операций. Например, chrome не смог отобразить wsdl файл веб-сервиса с русским именем.
Перейдите на вкладку "Прочее" и укажите параметр "URI пространство имен".
В документации об этом параметре написано чуть больше чем ничего, примерно то, что это поле служит для идентификации вашего веб-сервиса. Когда я делал свой первый веб-сервис, мне казалось что это ссылка на сайт, на котором я публикую свой веб-сервис и все наименования буду получаться через запрос к этому сайту. На самом деле "URI пространство имен" не что иное как строка определяющая название набора ваших имен (названий веб-сервиса, операций, параметров, типов данных и т.д.). То есть если вы объявите свой тип "integer" то xml-парсер не будет ругаться, так как этот тип принадлежит вашему пространству имен. Мало того если "URI пространство имен" будет содержать русские символы и не будет соответствовать стандарту как формат URI, платформа все равно опубликует такой веб-сервис, и он будет работать. Но по стандартам рекомендуется использовать URI ссылку. Я советую того же самого.
Простое и понятное объяснение пространства имен можно прочитать тут.
Поле "Пакеты XDTO" не обязательное. Оно определяет набор пакетов XDTO в которых вы можете оказать свои типы значений. Это не обязательное поле, по умолчанию вам всегда доступны типы пространства имен "http://www.w3.org/2001/XMLSchema". О пакетах XDTO я расскажу чуть позже.
"Имя файла публикации", это имя файла, в котором хранятся настройки веб-сервиса для Apache(путь к базе и другие) после публикации. Папка, в которой находится этот файл, определяется при публикации. О публикации на веб-сервере будет рассказано позже.
Веб-сервис создан, но еще нет ни одной функции которую он мог бы исполнить. Надо добавить операцию. Для этого добавьте в созданный веб-сервис операцию. Нажмите не веб-веб-сервис правой кнопкой и выберите "Добавить-Операция". Она будет к вашему операнду прибавлять 2 и возвращать значение. Давайте назовем ее "Plus2". Можно указать и русское название, многие клиенты его обработают, но все же могут возникнуть проблемы.
"Тип возвращаемого значения" это тип описанный в указанном вами пакете XDTO или же тип из пространства имен "http://www.w3.org/2001/XMLSchema". Именно в этом типе веб сервис будет возвращать значение.
"Возможно пустое значение" признак что ws-операция может не вернуть значение( nillable webkit-html-attribute-value" style="font-family: monospace; font-size: 13px;">true " ).
"В транзакции" указывает что код веб-сервиса будет выполняться в транзакции. А "Режим управления блокировкой данных" определяет тип блокировки данных при транзакции по умолчанию.
Установим тип возвращаемого значения в int. В поле "Имя метода" укажем имя "Plus2" для нового метода, который будет выполнять обработку. При нажатии на лупу метод будет автоматом создан в модуле веб-сервиса.
Напишем простой код.
Функция Plus2(Параметр)
Возврат Параметр+2;
КонецФункции
Вы заметили что на входе функции у нас есть параметр "Параметр". Для того что бы в метод этот параметр был передан надо добавить его в дереве метаданных. Для этого щелкните правой кнопкой по веб-операции Plus2 и выберите "Добавить-Параметр".
Давайте назовем его "Param". Названия параметров тоже можно указывать русскими, мало того класс SoapClient языка PHP работает с ними корректно, ведь параметры передаются через массив. Желательно использовать кодировку UTF-8.
Укажем "Тип значения" int из пространства имен "http://www.w3.org/2001/XMLSchema".
Цель блога описать интересные и полезные примеры программирования в системе 1С:Предприятие 8.
вторник, 18 июня 2013 г.
1С:Предприятие 8. Веб-сервисы. Возвращаем массив
При вызове ws-операций очень часто надо вернуть массив значений. В этой статье я расскажу как это сделать используя XDTOОбъект.
Создайте веб-сервис. В задайте свойство "URI пространства имен" веб-сервиса например "http://ghostaz.no-ip.org".
И создайте ws-операцию, например "ВозвратитьМассив".
У свойства укажите "Максимальное количество" равное -1. Это свойство и указывает что Элемент объекта "Свойство1" может быть повторен любое количество раз. Не забудьте указать тип свойства например string.
Теперь в ws-операции можно указывать XDTOОбъект "ТипОбъекта1" как Тип возвращаемого значения, но перед этим необходимо в у веб сервиса указать XDTO пакет:
Можно приступать к написанию кода. В обработке вызова операции мы создадим тип объекта XDTO, затем сам объект и в цикле добавим ему несколько элементов.
Читайте также: