maratz5
23.10.18 — 15:13
Всем доброго дня. Уже писал пост на эту тему.
Имеется сторонний SOAP веб-сервис. Вот выдержка из описания:
«API cистемы «****-Информ» представляет собой SOAP веб сервис, взаимодействие с которым осуществляется по протоколу HTTP или HTTPS. Пользователю предоставляется пара [логин, пароль], с помощью которых можно пользоваться сервисом.»
У этого веб-сервиса есть метод:
GetServiceInfo —
Возвращает информацию обо всех источниках, доступных пользователю, реквизитах поиска и наборах идентифицирующих свойств. Также возвращает примерное время ответа от источника в секундах. Вызывается без параметров.
Через программу SOAPUI мне удалось подрубиться к этому сервису и даже получаю отклики по этому методу.
Проблема возникла на стороне 1С: не знаю как синтаксически подрубиться.
Вот имеющийся код:
«ИмяПользователя = «****»;
Пароль = «****»;
ЗащищенноеСоединениеOpenSSL = Новый ЗащищенноеСоединениеOpenSSL(Новый СертификатКлиентаWindows(), Новый СертификатыУдостоверяющихЦентровWindows);
ИмяВебСервиса = «http://ws.prima-inform.ru/PrimaService.asmx?wsdl»;;;
WSОпределение = Новый WSОпределения(ИмяВебСервиса, ИмяПользователя, Пароль,,,ЗащищенноеСоединениеOpenSSL);
ВСДанные = WSОпределение.Сервисы[0];
Прокси = Новый WSПрокси(WSОпределение, ВСДанные.URIПространстваИмен, ВСДанные.Имя, ВСДанные.ТочкиПодключения[0].Имя,,,ЗащищенноеСоединениеOpenSSL);
Прокси.Пользователь = ИмяПользователя;
Прокси.Пароль = Пароль;
ЗапросТип = Прокси.ФабрикаXDTO.Тип(«http://ws.****-inform.ru/»;, «GetServiceInfo»);
Запрос = Прокси.ФабрикаXDTO.Создать(ЗапросТип);
Ответ = Прокси.GetServiceInfo();
В последней строчке кода выходит ошибка с кучей непонятной 1С-ку с небольшим стажем работы иероглифами.
Подскажите, может я не так подрубаюсь к сервису?
В инете инфы не нашел достаточной, а если и нашел, то не смог додуматься.
palsergeich
1 — 23.10.18 — 15:17
(0) Так по диагонали вроде написано все верно. Хотелось бы ошибку увидеть.
palsergeich
2 — 23.10.18 — 15:17
Может имелось ввиду Ответ = Прокси.GetServiceInfo(Запрос);
maratz5
3 — 23.10.18 — 15:19
(2) Да, верно. Там запрос передается. Выглядит так:
Прокси.GetServiceInfo(Запрос);
maratz5
4 — 23.10.18 — 15:20
Вот текст ошибки:
{ВнешняяОбработка.PrimaSOAP.Форма.Форма.Форма(48)}: Ошибка при вызове метода контекста (GetServiceInfo)
Ответ = Прокси.GetServiceInfo(Запрос);
по причине:
При вызове веб-сервиса произошла ошибка. Ошибка вызова операции сервиса: {http://ws.prima-inform.ru/}:PrimaService:GetServiceInfo()
по причине:
При вызове веб-сервиса произошла ошибка. Ошибка SOAP сервера: System.Web.Services.Protocols.SoapException: Server was unable to process request. —> System.AggregateException: One or more errors occurred. —> System.Reflection.TargetException: Non-static method requires a target.
at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at MongoDB.Driver.Linq.Processors.PartialEvaluator.ReflectionEvaluator.VisitMethodCall(MethodCallExpression node)
at MongoDB.Driver.Linq.Processors.PartialEvaluator.EvaluateSubtree(Expression subtree)
at MongoDB.Driver.Linq.Processors.PartialEvaluator.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
at MongoDB.Driver.Linq.Processors.PartialEvaluator.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
at MongoDB.Driver.Linq.Processors.PartialEvaluator.Visit(Expression node)
at MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate[TDocument](Expression`1 predicate, IBsonSerializer`1 parameterSerializer, IBsonSerializerRegistry serializerRegistry)
at MongoDB.Driver.MongoCollectionImpl`1.CreateFindOperation[TProjection](FilterDefinition`1 filter, FindOptions`2 options)
at MongoDB.Driver.MongoCollectionImpl`1.FindAsync[TProjection](IClientSessionHandle session, FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken)
at MongoDB.Driver.MongoCollectionImpl`1.<>c__DisplayClass43_0`1.<FindAsync>b__0(IClientSessionHandle session)
at MongoDB.Driver.MongoCollectionImpl`1.<UsingImplicitSessionAsync>d__101`1.MoveNext()
— End of stack trace from previous location where exception was thrown —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.IAsyncCursorSourceExtensions.<FirstOrDefaultAsync>d__5`1.MoveNext()
— End of inner exception stack trace —
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at Prima.Utils.Mongo.Mongo`1.Find(Expression`1 expression)
at Prima.Core.Repositories.Repository.GetUserId(String username, String password) in D:ProjectsPrima-Informprima.WebPrima.Core.RepositoriesRepository.cs:line 158
at Prima.Api.Ws2.PrimaService._tryAuth() in D:ProjectsPrima-Informprima.WebPrima.Api.Ws2PrimaService.asmx.cs:line 66
at Prima.Api.Ws2.PrimaService.tryAuth() in D:ProjectsPrima-Informprima.WebPrima.Api.Ws2PrimaService.asmx.cs:line 86
at Prima.Api.Ws2.PrimaService.GetServiceInfo() in D:ProjectsPrima-Informprima.WebPrima.Api.Ws2PrimaService.asmx.cs:line 95
— End of inner exception stack trace —
Код ошибки: Server
Техническая информация:
<detail xmlns:soap=»http://schemas.xmlsoap.org/soap/envelope/»; xmlns:xsd=»http://www.w3.org/2001/XMLSchema»; xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance»/>;
maratz5
5 — 23.10.18 — 15:23
(1) прикрепил текст ошибки
palsergeich
6 — 23.10.18 — 15:23
(2) Вы не заполнили этот объектЕсли посмотреть на него в SOAPUI то видно что ждется заполнение полей
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"; xmlns:ws="http://ws.prima-inform.ru/">;
<soapenv:Header>
<ws:AuthHeader>
<!--Optional:-->
<ws:Username>?</ws:Username>
<!--Optional:-->
<ws:Password>?</ws:Password>
<!--Optional:-->
<ws:PartnerId>?</ws:PartnerId>
</ws:AuthHeader>
</soapenv:Header>
<soapenv:Body>
<ws:GetServiceInfo/>
</soapenv:Body>
</soapenv:Envelope>
maratz5
7 — 23.10.18 — 15:25
(6) в SOAP UI я заполнял Username и Password. А в 1С — ке же я заполняю имя пользователя и пароль, разве не то? Как быть тогда?
palsergeich
8 — 23.10.18 — 15:26
ТО есть сам запрос без параметров, но требуются заполнение вот этой штуки
<soapenv:Header>
<ws:AuthHeader>
<!--Optional:-->
<ws:Username>?</ws:Username>
<!--Optional:-->
<ws:Password>?</ws:Password>
<!--Optional:-->
<ws:PartnerId>?</ws:PartnerId>
</ws:AuthHeader>
</soapenv:Header>
Если честно - не помню как с soapenv:Header работать
Cyberhawk
9 — 23.10.18 — 15:28
Если платформенные заголовки, что вокруг конверта, тебя не устраивают, то забудь про использование объектной модели работы с веб-сервисом из 1С. Делай на хттп-запросах.
maratz5
10 — 23.10.18 — 15:48
(8) Спасибо и на этом. Буду смотреть, как заполнять этот блок
maratz5
11 — 26.10.18 — 13:21
(9) В общем все получилось, использовал HTTP соединение и HTTP запросы. Все вроде бы хорошо отрабатывает, ответ приходит, как в SOAP UI.
Другой вопрос:
У этого сервиса есть метод «GetFullReport», вот выдержка из инструкции:
«Строит отчет по запросу. Метод можно выполнять, когда хотя бы один из источников уже обработал запрос. В отличие от GetReport данный метод возвращает ответ в более структурированном виде, также проводится некоторый анализ данных, в результате которого фильтруются нерелевантные записи. Структуру такого ответа см. в разделе Структуры отчета -> Структура отчета GetFullReport.»
На входе у этого метода следующие параметры:
— requestId (Идентификатор запроса)
— format (Формат отчета. В данном методе формат может принимать только следующие значения: Xml, Json, Pdf).
В SOAP UI формирую следующий XML:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"; xmlns:ws="http://ws.prima-inform.ru/">;
<soapenv:Header>
<ws:AuthHeader>
<!--Optional:-->
<ws:Username>***</ws:Username>
<!--Optional:-->
<ws:Password>***</ws:Password>
<!--Optional:-->
<ws:PartnerId>?</ws:PartnerId>
</ws:AuthHeader>
</soapenv:Header>
<soapenv:Body>
<ws:GetFullReport>
<ws:requestId>d2601e0b-ebfb-4c9a-9095-29d53e6a2c5c</ws:requestId>
<ws:format>3</ws:format>
</ws:GetFullReport>
</soapenv:Body>
</soapenv:Envelope>
В ответ приходит:
<soap:Envelope xmlns:soap=»http://schemas.xmlsoap.org/soap/envelope/»; xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance»; xmlns:xsd=»http://www.w3.org/2001/XMLSchema»>;
<soap:Body> <soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>System.Web.Services.Protocols.SoapException: Server was unable to read request. —> System.InvalidOperationException:
There is an error in XML document (15, 34). —> System.InvalidOperationException: Instance validation error: ‘3’ is not a valid value for ReportFormat.
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read20_ReportFormat(String s)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read49_GetFullReport()
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
— End of inner exception stack trace —
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters()
— End of inner exception stack trace —
at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters() at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()</faultstring> <detail/> </soap:Fault> </soap:Body> </soap:Envelope>
В чем может быть проблема? Обращаться к разработчикам сервиса?
eklmn
12 — 26.10.18 — 13:24
‘3’ is not a valid value for ReportFormat
и
— format (Формат отчета. В данном методе формат может принимать только следующие значения: Xml, Json, Pdf
найди отличия
maratz5
13 — 26.10.18 — 18:36
(12) да пробовал я и так «xml», та же ошибка. Видимо ругается на формат. Блин, может SOAP UI ограничен в возможностях или что еще может быть?
runoff_runoff
14 — 26.10.18 — 18:50
а helloWorld() работает?
palsergeich
15 — 26.10.18 — 21:55
(11) Заголовки в запросе ставишь?
Сервисы крайне чувствительны к заголовку Content-type, а при прямых запросах он автоматом не ставится
maratz5
16 — 29.10.18 — 16:11
(15) Content-Type: text/xml;charset=UTF-8
Ставлю такой. Все равно ошибка.
dezss
17 — 29.10.18 — 16:19
(13)
<s:enumeration value="Html"/>
<s:enumeration value="Pdf"/>
<s:enumeration value="Rtf"/>
<s:enumeration value="Json"/>
<s:enumeration value="Xml"/>
<s:enumeration value="Zip"/>
А ты кавычки ставил, когда формат передавал?
dezss
18 — 29.10.18 — 16:20
(17) + т.к. смотрю, что 3 у тебя без кавычек
maratz5
19 — 30.10.18 — 10:27
(17) Ставил кавычки — ошибка та же.
Очень странно, сейчас попробовал без кавычек отправить — пришел ответ тот который нужен. Очень странно. На тот момент, когда у меня была эта ошибка, я работал с одним логином и паролем, недавно у него срок истек. Сейчас попросил админов вебсервиса дать мне снова доступ к нему, теперь же все получается. Может быть такое, что у меня права были ограничены что???
maratz5
20 — 30.10.18 — 10:32
Друзья!
Ответ от веб сервиса приходит, только вот в нем содержится
одна очень длинная строка:
«PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8TWFpbkluZm8geG1sbnM6eHNkPSJodHRwOi8vd3d3LnczLm9yZy8yMDAx…..»
Это я так понимаю двоичные данные или что? И как их преобразовать в XML?
maratz5
21 — 30.10.18 — 10:44
(20) разобрался, нужно строку преобразовать в двоичные данные через Base64Значение, а потом можно через метод Записать() сохранить в xml.
А как можно не записывая в файл получить СтрокуXML?
maratz5
22 — 30.10.18 — 10:51
(21) Тоже разобрался:
ПолучитьСтрокуИзДвоичныхДанных(Base64Значение(СтрокаДвоичныеДанные_XML))
Всем спасибо.
CentrForward
23 — 30.10.18 — 11:32
(11) Автор, покажи, пожалуйста, как реализовал через HTTPСоединение и HTTP-запросы. Чтоб уж тема завершенная была. Интересно.
maratz5
24 — 30.10.18 — 12:01
(23) Вот пример кода, в котором вызываю метод «GetServiceInfo», стандартный метод, возвращающий ответ в виде XML об общей информации:
Хост = "ws.prima-inform.ru";HTTPСоединение = Новый HTTPСоединение(Хост, , ИмяПользователя, Пароль, , 100, Новый ЗащищенноеСоединениеOpenSSL());
ЗаголовокЗапросаHTTP = Новый Соответствие();
ЗаголовокЗапросаHTTP.Вставить("Content-Type", "text/xml;charset=UTF-8");
ЗаголовокЗапросаHTTP.Вставить("soapAction", "http://ws.prima-inform.ru/GetServiceInfo";);HTTPЗапрос = Новый HTTPЗапрос("/PrimaService.asmx?", ЗаголовокЗапросаHTTP);
СтрокаXML = "
|<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/""; xmlns:ws=""http://ws.prima-inform.ru/"">;
| <soapenv:Header>
| <ws:AuthHeader>
| <!--Optional:-->
| <ws:Username>*****</ws:Username>
| <!--Optional:-->
| <ws:Password>*****</ws:Password>
| <!--Optional:-->
| <ws:PartnerId>?</ws:PartnerId>
| </ws:AuthHeader>
| </soapenv:Header>
| <soapenv:Body>
| <ws:GetServiceInfo/>
| </soapenv:Body>
|</soapenv:Envelope>";HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаXML);
Результат = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Ответ = Результат.ПолучитьТелоКакСтроку();
В переменной "Ответ" как раз таки будет XML в виде строки
CentrForward
25 — 30.10.18 — 12:13
(24) Спасибо!
Всем привет! При обращении к методу сервиса 1с из 1с ошибка: «Ошибка SOAP сервера: Неизвестная ошибка. {WebСервис.NumerationSF.Модуль}: Ошибка при вызове метода контекста (ПрочитатьXDTO) по причине: {WebСервис.NumerationSF.Модуль}: Ошибка при вызове метода контекста (ПрочитатьXDTO) по причине: Несоответствие типов (параметр номер ‘1’)» Обращаюсь вот так: Определения = Новый WSОпределения(«ссылка на сервис»); Прокси = Новый WSПрокси(Определения, «;, «NumerationSF», «NumerationSFSoap»); из SOAPUI тот-же запрос работает. В чем ошибка?
Нужно смотреть в модуле вот этого вот : «NumerationSF» в строке . Скорее всего неправильно с точки зрения сервиса выглядит содержимое вот этого вот : «СтрокаXML».
А при запросе из soapui этот же запрос срабатывает…
Ну так сравни «СтрокаXML» в 1С и тоже самое в soapui.
в soapui обертка только есть стандартно. Не мешала никогда. почему-то на тип ругается: «Несоответствие типов (параметр номер ‘1’)»
«в soapui обертка только есть стандартно.» Это как понять? Метод вызывается вообще без параметра?
Сразу несколько вопросов NumerationSF и пространство имен Если хочешь получить объект XDTO из строки то
Ошибка преобразования данных XDTO: НачалоСвойства: { Форма: Элемент Тип: { по причине:
В базе сервиса тип параметра «string», а при создании ws-ссылки «anyType»
используй динамическое подключение если не знаешь какое пространство имен используешь
Ошибка преобразования данных XDTO:
в браузере string. Не понимаю, почему anyType у меня
Ошибка преобразования данных XDTO: НачалоСвойства: { Форма: Элемент Тип: { по причине: Ошибка преобразования данных XDTO: НачалоСвойства: Body Форма: Элемент Тип: {
по причине: Ошибка преобразования данных XDTO: НачалоСвойства: Body Форма: Элемент Тип: {
откуда anyType, если в браузере и в конфе сервиса string? И что с этим делать?
Если string, тогда зачем ты туда пихаешь ОбъектXDTO? Пихай стринг
Определения = Новый WSОпределения(«ссылка на сервис»); Прокси = Новый WSПрокси(Определения, «;;, «NumerationSF», «NumerationSFSoap»);
Внимательно посмотри на 12. И посмотри какое пространство имен у WSСервис.URIПространстваИмен
WSСервис.URIПространстваИмен = «;
«СтрокаXML» у тебя какой тип имеет?
{Форма.Форма.Форма}: Ошибка при вызове метода контекста (GetNumberSF) Ответ = Прокси.GetNumberSF(СтрокаXML); по причине: Несоответствие типов (параметр номер ‘1’)
ТипWSПараметра = Прокси.ФабрикаXDTO.Тип(«;;, «string»);
ТипWSПараметра = Прокси.ФабрикаXDTO.Тип(«;;;, «string»);
Ответ = Прокси.GetNumberSF(Парам);
Вообще то это стандартное пространство имен уже зашитое. А кто задал такое имя пространства имен? Если это сервис 1С
Ты бы хоть показал описание WSDL и типы используемые GetNumberSF
вот фрагмент описания: <definitions xmlns=»; xmlns:soap12bind=»; xmlns:soapbind=»; xmlns:tns=»; xmlns:xsd=»; xmlns:xsd1=»; name=»NumerationSF» targetNamespace=»; <types> <xs:schema xmlns:xs=»; xmlns:xs1=»; targetNamespace=»; elementFormDefault=»qualified»>
Если в 1с создать ws-ссылку — тип у параметра будет: anyType
Вариант работает, но на вход в процедуру сервиса приходит почему-то Строка, а не ОбъектXDTO. Из SOAPUI приходит ОбъектXDTO. Как сделать, чтоб приходил ОбъектXDTO?
Web-Service самописный? Где находится? Есть доступ к исходникам?
СтрокаТип = WSПрокси.ФабрикаXDTO.Тип(«;);
Выдернул из обработки клиент банка. Если не поможет, скидывай wsdl целиком
Измените пространство имен у Веб сервиса Неправильно. targetNamespace=»;; Замените на какойнибудь Ну и раз параметр строка Ответ = Прокси.GetNumberSF(СтрокаXML);
не, на входе получается Строка, а не ОбъектXDTO
на входе в сервисе все равно Строка получается
Еще раз задай нормальное пространство имен Судя по описанию у тебя параметр строка.
С с чем сравниваешь? Скачай Fiddler2 и смотри им какие запросы кто отправляет
В отладке сервиса — если из 1с запрос приходит — на входе Строка, из других систем — ОбъектXDTO
Ну ты читай, что я тебе пишу в 41 Например Так, а что у тебя реально представляет параметр в сервисе?
Прошу прощения, немного напутал. Если отправляю запрос из SOAPUI — на входе сервиса ОбъектXDTO и все отрабатывает без ошибки. Если отправляю из 1С — на входе тоже ОбъектXDTO, но видимо другой и ошибка появляется при попытке прочитать ОбъектXDTO: Разница в объектах: от SOAPUI в отладке вижу просто ОбъектXDTO; от 1с в отладке видны еще его поля, т.е. тэги xml, которую я передаю. Видимо как-то не так отправляю?
Ваще не пойму — почему туда приходит ОбъектXDTO, а не строка? В моей конфе в сервисы на вход приходит строка всегда, но тут платформа 8.3 (8.3.5.1186), а там 8.3 (8.3.6.1977). Может в платформе дело?
Нет не в платформа, а в способе отправки. Вопрос — почему разные ОбъектXDTO приходят от SOAPUI и от 1с?
Скорее всего у тебя URIПространстваИменСервиса не , а собственные. Посмотри в wsdl какие используются пространства имен.
Фидлером не смотрел какой запрос 1с формирует?
Так пространство имен и не стал переименовывать?
Тэги:
Комментарии доступны только авторизированным пользователям
В этой статье рассмотрим, как можно реализовать веб-сервис в расширении платформы 1С.
В качестве примера возьмем веб-сервис, позволяющий передавать информацию о клиентах из внешней CRM-системы во внутреннюю систему управленческого учета на «1С:Управление нашей фирмой».
Веб-сервис будет создан в расширении, чтобы сохранить конфигурацию на поддержке.
О чем эта статья
Материал статьи раскроет ответы на следующие вопросы:
- Как работать с XDTO-пакетами?
- Как создать веб-сервис и настроить его свойства?
- Как опубликовать веб-сервис на сервере?
Постановка задачи
Компания ведет учет в типовом решении фирмы «1С:Управление нашей фирмой» (УНФ). Для управления взаимоотношениями с клиентами используется облачная CRM-система. В CRM-систему вводят информацию о новых клиентах. Необходимо реализовать перенос сведений о новых клиентах в УНФ сразу же при регистрации данных в CRM-системе.
Рисунок 1. Схема работы
Данные должны передаваться одним параметром (структурой). Спецификация данных, передаваемые из CRM в УНФ приведены в таблице 1.
Таблица 1. Требования к данным для обмена
Данные | Имя cвойства | Тип | Ограничения |
Полное наименование | FullName | Строка | Обязательно для заполнения |
ИНН | INN | Строка(12) | Для ЮрЛица – длина 10 Для ИП – длина 12 Для ФизЛица – не заполняется Допускаются только цифры |
КПП | KPP | Строка(9) | Для ЮрЛица – длина 9 Для ФизЛица – не заполняется Допускаются только цифры |
Телефон | Phone | Строка(12) | Обязателен для заполнения формат +7 (NNN) NNN-NN-NN |
После создания контрагента в CRM-систему должен быть передан уникальный идентификатор. Идентификатор будет использоваться в дальнейшем для сопоставлении клиента в CRM и УНФ при обмене заказами. Необходимо реализовать описанный функционал без снятия УНФ с поддержки.
Обоснование выбора варианта решения
- Проанализируем требования. Добавлять клиентов надо «на лету», сразу же при вводе в CRM. Значит периодические обмены по расписанию нам не подходят.
- Выбранная CRM расположена в облаке, поэтому использовать COM-соединение не получится.
- В требованиях к передаваемым данным есть ограничения — на длину строк и на виды контрагентов. Выбирая между технологией обмена через http-сервисы и веб-сервисы, остановимся на веб-сервисах, так как типизация данных и настройка ограничений в них есть «из коробки». Дополнительным плюсом будет то, что веб-сервисы умеют «самодокументироваться», а значит мы экономим время на описании API для разработчиков CRM.
- Последнее требование — не снимать конфигурацию с поддержки.
Таким образом, для решения описанной задачи мы создадим расширение конфигурации. А в этом расширении реализуем веб-сервис для добавления информации о контрагентах.
Добавляем расширение
Начнем реализацию поставленной задачи и создадим новое расширение. Для этого откроем меню Конфигурация -> Расширения конфигурации.
Рисунок 2. Добавляем расширение
В открывшемся окне жмем кнопку Добавить, а затем заполняем окно создания расширения.
Рисунок 3. Заполняем свойства нового расширения
Префикс указывается для обеспечения уникальности расширений. Обычно в качестве префикса используют первые буквы названия компании или инициалы разработчика. Сохраним расширение, нажав ОК, а затем дважды щелкнем по строке расширения, чтобы его открыть.
Импортируем объекты метаданных
Теперь импортируем в расширение объекты для дальнейшей работы. Нам нужны:
- Справочник Контрагенты
- Справочник Виды контактной информации
- Перечисление Типы контактной информации
Начнем со справочника Контрагенты. Выделим его в основной конфигурации и вызовем контекстное меню Добавить в расширение.
Рисунок 4. Импортируем справочник
Затем добавим в расширение реквизиты справочника Контрагенты и табличную часть КонтактнаяИнформация.
В результате ветка Контрагенты в расширении должна выглядеть так:
Рисунок 5. Справочник «Контрагенты» в расширении
После чего добавим в расширение перечисления ВидыКонтрагентов и ТипыКонтактнойИнформации.
Идем дальше. Из справочника ВидыКонтактнойИнформации нам нужно предопределенное значение ТелефонКонтрагента. Выдяем в дереве метаданных справочник ВидыКонтактнойИнформации и переходим по гиперссылке Предопределенные:
Рисунок 6. Предопределенные элементы справочника
В ветке Контрагенты находим предопределенный элемент ТелефонКонтрагента.
Рисунок 7. Выбираем предопределенный элемент ТелефонКонтрагента
Выполняем команду контекстного меню Добавить в расширение. В расширение добавляется справочник ВидыКонтактнойИнформации и его предопределенный элемент ТелефонКонтрагента.
Рисунок 8. Справочник «Виды контактной информации» в расширении
С импортом объектов в расширение мы закончили. Теперь переходим к разработке веб-сервиса.
Как работают веб-сервисы
Веб-сервисы в 1C представляют собой реализацию протокола SOAP (от англ. Simple Object Access Protocol — простой протокол доступа к объектам). Архитектуру приложения на основе протокола SOAP можно представить в виде следующей схемы:
Рисунок 9. Архитектура приложений на основе протокола SOAP
Общий принцип работы веб-сервиса можно описать так: мы создаем некий функционал, чтобы предоставить его сторонним разработчикам. Для того, чтобы этот функционал был им доступен, мы размещаем его на веб-сервере (публикуем). При публикации веб-сервиса происходит размещение его описания в формате WSDL (WSDL – Web Service Definition Language). Это описание стандартизовано и содержит описание методов веб-сервиса и типов данных, которые могут передаваться между сервисом и его клиентом. Клиент сервиса получает описание сервиса в виде WSDL-файла и может начать обмениваться данными в соответствии с этим описанием. Обмен происходит по протоколу HTTP, а сообщения передаются в теле HTTP пакетов в формате XML.
Особенность этой технологии состоит в том, что нам не нужно формировать XML и HTTP-пакеты вручную. Современные среды разработки, в том числе и 1С, позволяют работать с веб-сервисами в объектной технике.
Создаем XDTO-пакет
XDTO-пакеты описывают типы данных, которые будут использоваться при обмене. Потребителями веб-сервисов могут быть программы, написанные на разных языках, поэтому веб-сервис должен представить свои данные в виде примитивных типов (их описание во всех языках равнозначно). XDTO-пакеты позволяют привести типы 1С к типам, которые описаны в общемировом стандарте W3C. Кроме того, мы можем описать набор ограничений, применяемых к данным.
Приступаем к созданию XDTO-пакета для нашего веб-сервиса. В дереве метаданных расширения в ветке Общие -> XDTO-пакеты добавим XDTO-пакет ak_Customers. В URI пространства имен указываем http://kursy-po-1c.ru/ws/wsextension.
Это не ссылка на реальный адрес в интернете, а просто строка-идентификатор пространства имен, который помогает однозначно идентифицировать типы данных с одинаковыми именами. Например, программист Иванов определил тип данных Customer c двумя свойствами Name и FullName, а программист Петров определил свой тип Customer со свойствами Name, INN, KPP.
Чтобы не возникало путаницы и проблем с одинаковыми названиями типов, применяются пространства имен. Пространство имен и имя типа должны однозначно идентифицировать тип данных. При описании типов данных для веб-сервисов принято в качестве пространства имен использовать URI, содержащие доменное имя разработчика. Это позволяет сделать пространство имен уникальным.
Рисунок 10. Свойства XDTO-пакета
Теперь жмем ссылку Открыть пакет и начинаем описывать типы данных.
Сначала опишем простые типы данных по которым нам нужно наложить ограничения. Это ИНН, КПП, Телефон.
ИНН по условиям задачи различается для ИП и для ЮрЛица.
Определим 2 простых типа: INN_IP и INN_UL. Для этого в форме редактирования пакета открываем меню Добавить -> ТипЗначения.
Рисунок 11. Добавляем тип значения в XDTO-пакет
Заполняем свойства как на рисунке ниже:
Рисунок 12. Свойства типа значения INN_IP
Здесь мы указали имя типа INN_IP (ИНН для ИП) и определили для него ограничение — это должна быть строка длиной 12 знаков.
Обратите внимание, что для названий типов веб-сервиса нужно выбирать англоязычные имена. В дальнейшем они будут использоваться на стороне клиента для генерации классов, а с кириллицей где-то могут возникнуть сложности.
Теперь нам нужно задать ограничение: 12 знаков должны быть цифрами. Выделяем свойство INN_IP и вызываем меню Добавить->Образец:
Рисунок 13. Добавляем шаблона заполнения INN_IP
Заполняем свойство образца шаблоном в виде регулярного выражения [0-9]{12}. То есть мы допускаем в значении 12 цифр от 0 до 9.
Рисунок 14. Шаблон заполнения INN_IP
Подобные действия нужно произвести с INN_UL (ИНН юрлица) и KPP (КПП):
Рисунок 15. Добавляем типы значений и устанавливаем шаблоны
И для телефона (шаблон [+][7][ ][(][0-9]{3}[)][ ][0-9]{3}[-][0-9]{2}[-][0-9]{2}):
Рисунок 16. Типа значения Phone и шаблон его заполнения
Теперь перейдем к определению типов для данных о клиентах.
У нас есть три типа клиентов: Юрлицо, ФизЛицо и ИП. Для всех типов клиентов правила заполнения ИНН и КПП отличаются. Можно сделать только один класс Customer и контроль заполнения ИНН и КПП производить программно, но удобнее это делать декларативно — чтобы уменьшить возможность ошибок. Мы создадим три комплексных типа: CustomerIP, CustomerUL и CustomerFL. Значения ИНН и КПП будем выбирать из ранее созданных типов значений.
Для создания клиента ФизЛицо выделим корень пакета и вызовем меню Добавить -> ТипОбъекта. В свойствах укажем следующие значения:
Рисунок 17. Свойства типа объекта CustomerFL
- CustomerFL — это имя типа. Должно быть на английском.
- ComplexType — базовый тип, аналогичный структуре.
Выделим тип объекта CustomerFL и вызовем меню Добавить->Свойство. Заполним в редакторе свойств значения:
Рисунок 18. Добавляем свойство FullName в тип объекта CustomerFL
- FullName — имя свойства. Должно быть на английском.
- Тип string — строковый тип.
- Поле FullName должно быть обязательно заполнено указываем Возможно пустое — Ложь.
Таким же образом добавим свойства Phone и GUID.
Рисунок 19. Добавляем свойство Phone в тип объекта CustomerFL
Рисунок 20 Добавляем свойство GUID в тип объекта CustomerFL
Затем добавим тип объекта CustomerIP с такими же свойствами, как у CustomerFL, добавив новое свойство INN.
Рисунок 21. Добавляем свойство INN в тип объекта CustomerIP
Дальше создадим тип объекта CustomerUL с такими же свойствами, как у CustomerIP. Добавим новое свойство KPP.
Рисунок 22. Добавляем свойство KPP в тип объекта CustomerUL
У свойства INN нужно изменить тип на INN_UL (http://kursy-po-1c.ru/ws/wsextension).
Рисунок 23. Добавляем свойство INN в тип объекта CustomerUL
Мы завершили создание XDTO-пакета.
Рисунок 24. Новый XDTO-пакет
Переходим к разработке веб-сервиса.
Создаем веб-сервис
В ветке метаданных Общие выделяем ветку Web-Сервисы. Вызываем контекстное меню Добавить и заполняем свойства нового веб-сервиса:
Рисунок 25. Заполняем свойства веб-сервиса
- Имя — ak_Customers
- ПакетыXDTO — http://kursy-po-1c.ru/ws/wsextension. Теперь сможем использовать типы данных, которые определены этом пакете.
- URI пространства — http://kursy-po-1c.ru/ws/wsextension. Пространство имен будет использоваться клиентами веб-сервиса.
- Имя файла публикации — Customers.1cws. Имя будет использоваться в URL для получения WSDL.
Теперь добавим метод веб-сервиса, который будет записывать в УНФ нового контрагента-физлицо. Вызываем меню Добавить->Операция и заполняем свойства:
Рисунок 26. Свойства метода AddCustomerFL
- Имя — имя метода веб-сервиса. Будет использоваться при обращении к сервису извне.
- Тип возвращаемого значения — тип данных, который возвращает сервис. В нашем случае это строка-уникальный идентификатор, который в будет возвращен в CRM.
- Имя процедуры — имя процедуры в модуле сервиса, которая будет выполняться при обращении к этому методу.
Далее мы добавим параметры, которые будут передаваться в веб-сервис.
В нашем случае это один параметр — Customer. Для добавления параметра выделяем операцию веб-сервиса и вызываем контекстное меню Добавить->Параметр. В свойствах этого параметра заполняем свойства:
Рисунок 27. Свойства параметра Customer
- Имя — имя параметра метода сервиса. Будет виден на клиенте веб-сервиса.
- Тип значения — тип значения, определенный в нашем пакете.
Добавим еще две операции:
- AddCustomerIP
- AddCustomerUL.
Можно сделать это копированием. Затем нужно поменять имена операций, имена процедур-обработчиков (AddCustomerIP и AddCustomerUL) и типы параметров. Для AddCustomerIP тип параметра установим CustomerIP, а для AddCustomerUL — CustomerUP.
Теперь нужно создать процедуры-обработчики методов сервиса.
//Добавляем ФизЛицо Функция AddCustomerFL(Customer) Возврат ДобавитьКлиента(Customer, Перечисления.ВидыКонтрагентов.ФизическоеЛицо); КонецФункции //Добавляем ЮрЛицо Функция AddCustomerUL(Customer) Возврат ДобавитьКлиента(Customer, Перечисления.ВидыКонтрагентов.ЮридическоеЛицо); КонецФункции //Добавляем ИП Функция AddCustomerIP(Customer) Возврат ДобавитьКлиента(Customer, Перечисления.ВидыКонтрагентов.ИндивидуальныйПредприниматель); КонецФункции //Добавляем контрагента в базу УНФ Функция ДобавитьКлиента(Клиент, ВидКонтрагента) //Создаем нового контрагента и заполняем общие реквищиты НовыйКлиент = Справочники.Контрагенты.СоздатьЭлемент(); НовыйКлиент.ВидКонтрагента = ВидКонтрагента; НовыйКлиент.Наименование = Клиент.FullName; НовыйКлиент.НаименованиеПолное = Клиент.FullName; НовыйКлиент.Покупатель = Истина; //Для ЮрЛица и ИП заполняем ИНН Если ВидКонтрагента <> Перечисления.ВидыКонтрагентов. ФизическоеЛицо Тогда НовыйКлиент.ИНН = Клиент.INN; КонецЕсли; //Для ЮрЛица заполняем КПП Если ВидКонтрагента = Перечисления.ВидыКонтрагентов.ЮридическоеЛицо Тогда НовыйКлиент.КПП = Клиент.KPP; КонецЕсли; //Заполняем контактные данные Телефон = НовыйКлиент.КонтактнаяИнформация.Добавить(); Телефон.Тип = Перечисления.ТипыКонтактнойИнформации.Телефон; Телефон.Вид = Справочники.ВидыКонтактнойИнформации.ТелефонКонтрагента; Телефон.НомерТелефона = Клиент.Phone; Телефон.Представление = Клиент.Phone; //Записываем клиента в базу НовыйКлиент.Записать(); //Возвращаем ссылку в виде уникального идентификатора (GUID) Возврат XMLСтрока(НовыйКлиент.Ссылка); КонецФункции
Код простой и каких-то особых комментариев не требует.
Публикуем веб-сервис на сервере
Для публикации веб-сервиса должны быть установлены:
- Веб-сервер (Apache или IIS)
- Платформа 8.3.7 и выше с установленным расширением веб-сервера
О подготовке рабочего окружения можно прочитать в статье Как настроить обмен 1С с интернет-сервисами.
Для публикации веб-сервиса нужно запустить конфигуратор с правами администратора. Для этого вызываем контекстное меню и выбираем «Запуск от имени администратора»:
Рисунок 28. Запускаем конфигуратор от имени администратора
После открываем меню Администрирование->Публикация на веб-сервере. В открывшемся окне заполняем настройки:
Рисунок 29. Публикация веб-сервиса
- Имя — имя базы для публикации на сервере. Будет являться частью URL.
- Веб-сервер — на нем будет опубликована база. В нашем случае используется Apache 2.4.
- Каталог — место на диске, куда будет помещен default.vrd.
- Публиковать веб-сервисы — отмечаем.
- Публиковать веб-сервисы расширений по умолчанию — отмечаем, чтобы веб-сервисы были доступны из расширений.
Жмем Опубликовать.
Проверим, что веб-сервис опубликовался. Для этого запустим браузер и в адресной строке введем http://localhost/UNF/ws/Customers.1cws?wsdl. В результате в браузере должен отобразиться XML.
Рисунок 30. Проверяем работу веб-сервиса
Если в вашей базе есть пользователи, то при обращении по указанной ссылке будет запрошен логин и пароль. Нужно ввести логин и пароль администратора информационной базы.
Чтобы в дальнейшем не отвлекаться на пароли при изучении статьи (тему безопасности мы сознательно опускаем), откроем в текстовом редакторе файл default.vrd, (он лежит в каталоге, указанном при публикации). В него запишем логин и пароль в строке подключения: ib=”File="D:1CBaseUNF";usr=admin;pwd=12345;”. Логин, пароль и путь должны быть от вашей базы 1С.
Тестируем веб-сервис
Для проверки работоспособности сервера можно создать отдельную базу 1С и добавить в ней обработку ТестВебСервера со следующими реквизитами:
- FullName, строка(100)
- INN, строка(12)
- KPP, строка(9)
- Phone, строка(20)
Реквизиты выводим на форму и добавляем три кнопки:
- Создать ФизЛицо
- Создать ЮрЛицо
- Создать ИП.
Рисунок 31. Обработка для проверки веб-сервиса
В модуле формы напишем такой код:
//1. Обработчики кнопок //Обработчик кнопки СоздатьФизЛицо &НаКлиенте Процедура СоздатьФизЛицо(Команда) СоздатьКлиентаНаСервере("CustomerFL"); КонецПроцедуры //Обработчик кнопки СоздатьИП &НаКлиенте Процедура СоздатьИП(Команда) СоздатьКлиентаНаСервере("CustomerIP"); КонецПроцедуры //Обработчик кнопки СоздатьЮрЛицо &НаКлиенте Процедура СоздатьЮрЛицо(Команда) СоздатьКлиентаНаСервере("CustomerUL"); КонецПроцедуры //Создание клиента &НаСервере Процедура СоздатьКлиентаНаСервере(ТипКлиента) //2. Получаем описание сервиса ВСОпределение = Новый WSОпределения("http://localhost/UNF/ws/Customers.1cws?wsdl"); //3. Создаем прокси для обращения к сервису Прокси = Новый WSПрокси(ВСОпределение, "http://kursy-po-1c.ru">kursy-po-1c.ru/ws/wsextension", "ak_Customers", "ak_CustomersSoap"); //4. Получаем тип клиента по URI пространству имен и имени типа ТипКлиент = Прокси.ФабрикаXDTO.Тип("http://kursy-po-1c.ru">kursy-po-1c.ru/ws/wsextension", ТипКлиента); //5. Создаем XDTOОбъект заданного типа Клиент = Прокси.ФабрикаXDTO.Создать(ТипКлиент) ; //6. Заполняем данные Клиента данными, введенными в форме ЗаполнитьЗначенияСвойств(Клиент, Объект); //7. В зависимости от типа клиента вызываем соответствующий метод веб-сервиса Если ТипКлиента = "CustomerFL" Тогда Объект.GUID = Прокси.AddCustomerFL(Клиент); ИначеЕсли ТипКлиента = "CustomerIP" Тогда Объект.GUID = Прокси.AddCustomerIP(Клиент); ИначеЕсли ТипКлиента = "CustomerUL" Тогда Объект.GUID = Прокси.AddCustomerUL(Клиент); КонецЕсли; КонецПроцедуры
Прокомментируем код:
- В обработчиках кнопок вызываем процедуру СоздатьКлиентаНаСервере() и передаем название типа клиента в виде строки.
- Получаем WSDL-описание веб сервиса, опубликованного по указанному в параметрах URL. На основании него создается объект WSОпределение.
- Создаем объект Прокси для работы с сервисом. Он позволяет обращаться к веб-сервису, вызывая его методы в привычном объектном стиле. В качестве параметров передаем WSОпределение сервиса, созданное на предыдущем шаге, пространство имен веб-сервиса, имя веб-сервиса и точку подключения. Имя точки подключения формируется путем добавления к имени сервиса суффикса Soap (так формирует WSDL 1C).
- Получаем тип клиента по URI пространства имен.
- На основании типа клиента, полученного на предыдущем шаге, создаем XDTOОбъект Клиент. По структуре этот объект будет соответствовать структуре типа, который мы определяли в нашем XDTO-пакете.
- Заполняем значения реквизитов клиента данными, введенными в форме;
- В зависимости от переданного в процедуру типа клиента, мы вызываем разные методы веб-сервиса. «Под капотом» этого вызова произойдет сериализация данных в XML, валидация XML, формирование HTTP пакета и отправка его на сервер.
С этой обработкой можно поэксперементировать. Попробуйте создавать клиентов разных типов, введя корректные данные и некорректные. Если вы попытаетесь ввести в ИНН буквы или заполнить телефон, не соблюдая формат, то появится окно ошибки.
Итак, в данной статье мы познакомились с возможностями платформы по разработке веб-сервисов без снятия конфигурации с поддержки. Создали расширение, импортировали в расширение нужные нам объекты метаданных и описали модель данных для обмена. Создали и опубликовали веб-сервис. Написали обработку на 1С для проверки работоспособности этого сервиса.
На этом пока закончим, но не остановимся
Об авторе
Автор статьи – Алексей Дубровин, г. Челябинск
E-mail: dubrovin1973@gmail.com
Нужно быстро разобраться в работе расширений?
Чтобы быстро и полностью освоить все возможности расширений, рекомендуем пройти наш учебный курс Разработка расширений и технологии доработки конфигураций 1С без снятия с поддержки.
20.07.15 — 11:46
Всем привет!
При обращении к методу сервиса 1с из 1с ошибка:
«Ошибка SOAP сервера: Неизвестная ошибка. {WebСервис.NumerationSF.Модуль(7)}: Ошибка при вызове метода контекста (ПрочитатьXDTO)
по причине:
{WebСервис.NumerationSF.Модуль(7)}: Ошибка при вызове метода контекста (ПрочитатьXDTO)
по причине:
Несоответствие типов (параметр номер ‘1’)»
Обращаюсь вот так:
Определения = Новый WSОпределения(«ссылка на сервис»);
Прокси = Новый WSПрокси(Определения, «http://www.w3.org/2001/XMLSchema»;, «NumerationSF», «NumerationSFSoap»);
WSПараметр = СериализаторXDTO.ЗаписатьXDTO(СтрокаXML);
Ответ = Прокси.GetNumberSF(WSПараметр);
из SOAPUI тот-же запрос работает. В чем ошибка?
1 — 20.07.15 — 11:47
Прокси тут лишний
2 — 20.07.15 — 11:50
тип параметра anyType
3 — 20.07.15 — 11:51
(0) Нужно смотреть в модуле вот этого вот : «NumerationSF» в строке (7).
Скорее всего неправильно с точки зрения сервиса выглядит содержимое вот этого вот : «СтрокаXML».
4 — 20.07.15 — 11:57
(3) А при запросе из soapui этот же запрос срабатывает…
5 — 20.07.15 — 11:58
(4) Ну так сравни «СтрокаXML» в 1С и тоже самое в soapui.
6 — 20.07.15 — 12:05
(5) в soapui обертка только есть стандартно. Не мешала никогда.
почему-то на тип ругается: «Несоответствие типов (параметр номер ‘1’)»
7 — 20.07.15 — 12:08
(6) «в soapui обертка только есть стандартно.» Это как понять? Метод вызывается вообще без параметра?
8 — 20.07.15 — 12:12
Сразу несколько вопросов
NumerationSF и пространство имен http://www.w3.org/2001/XMLSchema
Если хочешь получить объект XDTO из строки то
ЧтениеXML= новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(СтрокаXML);
ЧтениеXML.ПерейтиКСодержимому();
WSПараметр =Прокси.Фабрика.ПрочитатьXML(ЧтениеXML,Фабрика.Тип(ЧтениеXML.URIПространстваИмен,ЧтениеXML.Имя));
9 — 20.07.15 — 12:13
Фабрика=Прокси.ФабрикаXDTO;
WSПараметр =Фабрика.ПрочитатьXML(ЧтениеXML,Фабрика.Тип(ЧтениеXML.URIПространстваИмен,ЧтениеXML.Имя));
10 — 20.07.15 — 12:23
(8) Ошибка преобразования данных XDTO:
НачалоСвойства: {http://www.w3.org/2001/XMLSchema}anyType Форма: Элемент Тип: {http://www.w3.org/2001/XMLSchema}anyType
по причине:
11 — 20.07.15 — 12:25
В базе сервиса тип параметра «string», а при создании ws-ссылки «anyType»
12 — 20.07.15 — 12:27
(0)
используй динамическое подключение если не знаешь какое пространство имен используешь
ОпределениеТ=Новый WSОпределения(«http://домен_сайта/имя_публикации_базы/ws/имя_веб_сервиса?wsdl»;);
WSСервис=ОпределениеТ.Сервисы[0];
ПроксиWS=Новый WSПрокси(ОпределениеТ, WSСервис.URIПространстваИмен, WSСервис.Имя, WSСервис.ТочкиПодключения[0].Имя);
ПроксиWS.Пользователь = «ХХХ»;
ПроксиWS.Пароль = «УУУУ»;
ПроксиWS.ВызватьКакойтоМетод();
13 — 20.07.15 — 12:34
Ошибка преобразования данных XDTO:
14 — 20.07.15 — 12:36
в браузере string.
Не понимаю, почему anyType у меня
15 — 20.07.15 — 12:45
(8)Ошибка преобразования данных XDTO:
НачалоСвойства: {http://www.w3.org/2001/XMLSchema}anyType Форма: Элемент Тип: {http://www.w3.org/2001/XMLSchema}anyType
по причине:
Ошибка преобразования данных XDTO:
НачалоСвойства: Body Форма: Элемент Тип: {http://www.w3.org/2001/XMLSchema}anyType
16 — 20.07.15 — 13:02
Определения = Новый WSОпределения(«»);
Прокси = Новый WSПрокси(Определения, «http://www.w3.org/2001/XMLSchema»;, «NumerationSF», «NumerationSFSoap»);
Фабрика=Прокси.ФабрикаXDTO;
ЧтениеXML= новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(СтрокаXML);
ЧтениеXML.ПерейтиКСодержимому();
ТипWSПараметра = Прокси.ФабрикаXDTO.Тип(«http://www.w3.org/2001/XMLSchema»;, «string»);
WSПараметр =Прокси.ФабрикаXDTO.ПрочитатьXML(ЧтениеXML, ТипWSПараметра);
Ответ = Прокси.GetNumberSF(WSПараметр);
{Форма.Форма.Форма(67)}: Ошибка при вызове метода контекста (ПрочитатьXML)
WSПараметр =Прокси.ФабрикаXDTO.ПрочитатьXML(ЧтениеXML, ТипWSПараметра);
по причине:
Ошибка преобразования данных XDTO:
НачалоСвойства: Body Форма: Элемент Тип: {http://www.w3.org/2001/XMLSchema}anyType
17 — 20.07.15 — 13:04
откуда anyType, если в браузере и в конфе сервиса string?
И что с этим делать?
18 — 20.07.15 — 13:13
Если string, тогда зачем ты туда пихаешь ОбъектXDTO? Пихай стринг
19 — 20.07.15 — 13:14
Определения = Новый WSОпределения(«ссылка на сервис»);
Прокси = Новый WSПрокси(Определения, «http://www.w3.org/2001/XMLSchema»;;, «NumerationSF», «NumerationSFSoap»);
//Это тут не нужно
//WSПараметр = СериализаторXDTO.ЗаписатьXDTO(СтрокаXML);
//Ответ = Прокси.GetNumberSF(WSПараметр);
Ответ = Прокси.GetNumberSF(СтрокаXML);
//Если взлетит — с тебя 500 р
20 — 20.07.15 — 13:42
(17) Внимательно посмотри на 12. И посмотри какое пространство имен у WSСервис.URIПространстваИмен
21 — 20.07.15 — 14:13
(20) WSСервис.URIПространстваИмен = «http://www.w3.org/2001/XMLSchema»;
22 — 20.07.15 — 14:17
«СтрокаXML» у тебя какой тип имеет?
23 — 20.07.15 — 14:18
(19)
{Форма.Форма.Форма(103)}: Ошибка при вызове метода контекста (GetNumberSF)
Ответ = Прокси.GetNumberSF(СтрокаXML);
по причине:
Несоответствие типов (параметр номер ‘1’)
24 — 20.07.15 — 14:19
(22) Строка
25 — 20.07.15 — 14:22
ТипWSПараметра = Прокси.ФабрикаXDTO.Тип(«http://www.w3.org/2001/XMLSchema»;;, «string»);
Парам = Прокси.ФабрикаXDTO.Создать(ТипWSПараметра);
ВидДокумента.Key = «Название_параметра»;
ВидДокумента.Value = СтрокаXML;
ВидДокумента.ValueType = «string»;
26 — 20.07.15 — 14:22
ТипWSПараметра = Прокси.ФабрикаXDTO.Тип(«http://www.w3.org/2001/XMLSchema»;;;, «string»);
Парам = Прокси.ФабрикаXDTO.Создать(ТипWSПараметра);
Парам.Key = «Название_параметра»;
Парам.Value = СтрокаXML;
Парам.ValueType = «string»;
27 — 20.07.15 — 14:23
Ответ = Прокси.GetNumberSF(Парам);
28 — 20.07.15 — 14:23
Попробуй так
29 — 20.07.15 — 14:41
Вообще то http://www.w3.org/2001/XMLSchema это стандартное пространство имен уже зашитое.
А кто задал такое имя пространства имен? Если это сервис 1С
30 — 20.07.15 — 14:46
Ты бы хоть показал описание WSDL и типы используемые GetNumberSF
31 — 20.07.15 — 14:46
Или выложи WSDL
32 — 20.07.15 — 14:49
(28) Параметр = неопределено
33 — 20.07.15 — 14:50
(30) тип 1 — string
34 — 20.07.15 — 14:52
(30) вот фрагмент описания:
<definitions xmlns=»http://schemas.xmlsoap.org/wsdl/»; xmlns:soap12bind=»http://schemas.xmlsoap.org/wsdl/soap12/»; xmlns:soapbind=»http://schemas.xmlsoap.org/wsdl/soap/»; xmlns:tns=»http://www.w3.org/2001/XMLSchema»; xmlns:xsd=»http://www.w3.org/2001/XMLSchema»; xmlns:xsd1=»http://www.w3.org/2001/XMLSchema»; name=»NumerationSF» targetNamespace=»http://www.w3.org/2001/XMLSchema»>;
<types>
<xs:schema xmlns:xs=»http://www.w3.org/2001/XMLSchema»; xmlns:xs1=»http://www.w3.org/2001/XMLSchema»; targetNamespace=»http://www.w3.org/2001/XMLSchema»; elementFormDefault=»qualified»>
<xs:element name=»GetNumberSF»>
<xs:complexType>
<xs:sequence>
<xs:element name=»RequestXML» type=»xs:string»/>
</xs:sequence>
</xs:complexType>
</xs:element>
35 — 20.07.15 — 14:54
Если в 1с создать ws-ссылку — тип у параметра будет: anyType (http://www.w3.org/2001/XMLSchema)
36 — 20.07.15 — 14:57
Скинь wsdl целиком
37 — 20.07.15 — 15:00
Вариант (0) работает, но на вход в процедуру сервиса приходит почему-то Строка, а не ОбъектXDTO. Из SOAPUI приходит ОбъектXDTO.
Как сделать, чтоб приходил ОбъектXDTO?
38 — 20.07.15 — 15:04
Web-Service самописный? Где находится? Есть доступ к исходникам?
39 — 20.07.15 — 15:09
СтрокаТип = WSПрокси.ФабрикаXDTO.Тип(«http://www.w3.org/2001/XMLSchema»,»string»;);
СтрокаЗначение = WSПрокси.ФабрикаXDTO.Создать(СтрокаТип,СтрокаXML);
Ответ = WSПрокси.GetNumberSF(СтрокаЗначение);
40 — 20.07.15 — 15:13
Выдернул из обработки клиент банка. Если не поможет, скидывай wsdl целиком
41 — 20.07.15 — 15:29
Измените пространство имен у Веб сервиса
Неправильно.
targetNamespace=»http://www.w3.org/2001/XMLSchema»>;;
Замените на какойнибудь
http://www.ИмяВашейКомпании.ru
Ну и раз параметр строка
Ответ = Прокси.GetNumberSF(СтрокаXML);
42 — 20.07.15 — 15:34
(39) не, на входе получается Строка, а не ОбъектXDTO
43 — 20.07.15 — 15:47
(8) на входе в сервисе все равно Строка получается
44 — 20.07.15 — 15:54
(43) Еще раз задай нормальное пространство имен
Судя по описанию у тебя параметр строка.
45 — 20.07.15 — 15:55
(42) С с чем сравниваешь?
Скачай Fiddler2 и смотри им какие запросы кто отправляет
46 — 20.07.15 — 15:56
47 — 20.07.15 — 16:14
(44) а какое нормальное?
48 — 20.07.15 — 16:34
(45) В отладке сервиса — если из 1с запрос приходит — на входе Строка, из других систем — ОбъектXDTO
49 — 20.07.15 — 16:49
(47) Ну ты читай, что я тебе пишу в 41
Например http://www.ИмяВашейКомпании.ru
(48) Так, а что у тебя реально представляет параметр в сервисе?
Фабрика=Прокси.ФабрикаXDTO;
Тип=Фабрика.Тип(ПространствоИмен,НазваниеТипа);
Парам=Фабрика.Создать(Тип);
50 — 21.07.15 — 09:19
(49) Прошу прощения, немного напутал.
Если отправляю запрос из SOAPUI — на входе сервиса ОбъектXDTO и все отрабатывает без ошибки.
Если отправляю из 1С — на входе тоже ОбъектXDTO, но видимо другой и ошибка появляется при попытке прочитать ОбъектXDTO:
Сериализатор = Новый СериализаторXDTO(ФабрикаXDTO);
СтрокаХМЛ = Сериализатор.ПрочитатьXDTO(RequestXML);
Разница в объектах:
от SOAPUI в отладке вижу просто ОбъектXDTO;
от 1с в отладке видны еще его поля, т.е. тэги xml, которую я передаю.
Видимо как-то не так отправляю?
51 — 21.07.15 — 09:20
А отправляю вот так:
ЧтениеXML= новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(СтрокаXML);
ЧтениеXML.ПерейтиКСодержимому();
Определения = Новый WSОпределения(«http://10.6.0.47/b83Services/ws/NumerationSF.1cws?wsdl»;);
WSПрокси = Новый WSПрокси(Определения, «http://www.w3.org/2001/XMLSchema»;, «NumerationSF», «NumerationSFSoap»);
WSПараметр = WSПрокси.ФабрикаXDTO.ПрочитатьXML(ЧтениеXML, WSПрокси.ФабрикаXDTO.Тип(ЧтениеXML.URIПространстваИмен,ЧтениеXML.Имя));
Ответ = WSПрокси.GetNumberSF(WSПараметр);
52 — 21.07.15 — 09:35
Ваще не пойму — почему туда приходит ОбъектXDTO, а не строка?
В моей конфе в сервисы на вход приходит строка всегда, но тут платформа 8.3 (8.3.5.1186), а там 8.3 (8.3.6.1977). Может в платформе дело?
53 — 21.07.15 — 09:39
(52) Нет не в платформа, а в способе отправки.
Вопрос — почему разные ОбъектXDTO приходят от SOAPUI и от 1с?
54 — 21.07.15 — 09:48
Скорее всего у тебя URIПространстваИменСервиса не http://www.w3.org/2001/XMLSchema, а собственные. Посмотри в wsdl какие используются пространства имен.
55 — 21.07.15 — 09:57
56 — 21.07.15 — 10:09
Фидлером не смотрел какой запрос 1с формирует?
57 — 21.07.15 — 10:11
Сделай как в(45)
Serginio1
58 — 21.07.15 — 11:18
(51) Так пространство имен и не стал переименовывать?
-
-
July 22 2022, 21:26
- IT
- Cancel
Хочу рассказать об ошибках, с которыми столкнулся при разработке веб-сервисов на 1С. Статью буду дополнять по мере получения опыта.
1. Это сообщение об ошибке при подключении к веб сервису из PHP.
[31-Mar-2013 05:32:02 UTC] PHP Fatal error: SOAP-ERROR: Parsing WSDL: Couldn’t load from ‘http://test.ru/test/ws/WebServices?wsdl’ : failed to load external entity
Данное сообщение говорит лишь о недоступности веб-сервера, на котором опубликована база. В этом случае попробуйте вручную вызвать http://test.ru/test/ws/WebServices?wsdl и убедиться, что WSDL формируется. Если не формируется, значит либо веб-сервер выключен, либо база опубликована по другому адресу или порту, либо блокирует фаервол. Могут быть и другие причины.
2. 02-Apr-2013 13:46:10 UTC] PHP Fatal error: Uncaught SoapFault exception: [HTTP] Error Fetching http headers in /home/users/b/test/domains/test.ru/testDIR/test.php:169
Эта ошибка возникает если WSDL возвращается с ошибкой. Есть несколько причин для этой ошибки:
- Несогласованность пространств имен в конфигурации. Например в ws-операции тип возвращаемого значения не соответствует типу из XDTO. Это может возникнуть при сменен URI пространства имен пакета XDTO.
- Возникает если в PHP включить кеш WSDL. Кеш запоминает WSDL и при каждом вызове веб-операции не запрашивает его, но если вы поменяли веб-сервис, то произойдет ошибка. Вообще, при разработке кеш стоит отключить, а если уже все работает то для скорости лучше включить. Ускорение при отключенном кеше заметное. Для примера скажу, что создание объекта SoapClient с выключенным кешем занимает примерно 2 сек, а с включенным — за сотые доли секунды. Отключить можно так:
ini_set(«soap.wsdl_cache_enabled», 0);
или
$client = new SoapClient(‘http://somewhere.com/?wsdl’, array(‘cache_wsdl’ => 0));
3. Ошибка SOAP сервера: Неизвестная ошибка. bad allocation.
Скорее всего недостаток оперативной памяти — проверьте запрос и результат вывода веб сервиса. Запрос может быть сложным, потому может быстро исчерпать оперативную память.
Re: 1с: Заказы
Общие модули -> МобильноеПриложениеЗаказы Клиентов
Ошибка в 315 строкеЕсли Число(ВерсияМобильногоПри� �ожения) <> 1 Тогда // это 315 строка
СтруктураОтвета.Success = Ложь;
СтруктураОтвета.ResultMessage = НСтр(«ru = ‘Требуется обновление мобильного приложения.'»);
Возврат ПодготовитьОтветWS(Структу� �аОтвета, «Permit»);
КонецЕсли;Я закомментировал данное условие. Теперь ошибка при синхронизации следующая «не найден узел обмена для пользователя: admin»
———- Post added at 19:40 ———- Previous post was at 19:24 ———-В разделе CRM и продажи включил «синхронизацию», в настройки синхронизации добавил логин с которого я пытаюсь войти. теперь пишет ошибку «ошибка записи настроек». не знаю уже что делать
Содержание статей: 1С:Предприятие 8. Веб-сервисы
Предыдущая статья: 1С:Предприятие 8. Веб-сервисы. Возвращаем массив
Хочу рассказать об ошибках, с которыми столкнулся при разработке веб-сервисов на 1С. Статью буду дополнять по мере получения опыта.
1
Это сообщение об ошибке при подключении к веб сервису из PHP.
[31-Mar-2013 05:32:02 UTC] PHP Fatal error: SOAP-ERROR: Parsing WSDL: Couldn’t load from ‘http://test.ru/test/ws/WebServices?wsdl’ : failed to load external entity
Данное сообщение говорит лишь о недоступности веб-сервера, на котором опубликована база. В этом случае попробуйте вручную вызвать http://test.ru/test/ws/WebServices?wsdl и убедиться, что WSDL формируется. Если не формируется, значит либо веб-сервер выключен, либо база опубликована по другому адресу или порту, либо блокирует фаервол. Могут быть и другие причины.
2
02-Apr-2013 13:46:10 UTC] PHP Fatal error: Uncaught SoapFault exception: [HTTP] Error Fetching http headers in /home/users/b/test/domains/test.ru/testDIR/test.php:169
Эта ошибка возникает если WSDL возвращается с ошибкой. Есть несколько причин для этой ошибки:
- Несогласованность пространств имен в конфигурации. Например в ws-операции тип возвращаемого значения не соответствует типу из XDTO. Это может возникнуть при сменен URI пространства имен пакета XDTO.
- Возникает если в PHP включить кеш WSDL. Кеш запоминает WSDL и при каждом вызове веб-операции не запрашивает его, но если вы поменяли веб-сервис, то произойдет ошибка. Вообще, при разработке кеш стоит отключить, а если уже все работает то для скорости лучше включить. Ускорение при отключенном кеше заметное. Для примера скажу, что создание объекта SoapClient с выключенным кешем занимает примерно 2 сек, а с включенным — за сотые доли секунды. Отключить можно так:
ini_set
(
"soap.wsdl_cache_enabled"
, 0);
или
$client
=
new
SoapClient(
'http://somewhere.com/?wsdl'
,
array
(
'cache_wsdl'
=> 0));
3
Ошибка SOAP сервера: Неизвестная ошибка. bad allocation.
Скорее всего недостаток оперативной памяти — проверьте запрос и результат вывода веб сервиса. Запрос может быть сложным, потому может быстро исчерпать оперативную память.