AXForum  
Вернуться   AXForum > Microsoft Dynamics NAV > NAV: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.01.2016, 11:35   #1  
poul_and is offline
poul_and
Участник
 
56 / 12 (1) ++
Регистрация: 08.04.2003
Появилась необходимость отправлять информацию в виде XML фаилов в SOAP пакетах и обрабатывать полученные ответы.
С одним сервисом кое как справился - используя SOAPUI, через командную строку отсылая заранее поготовленные запросы и передавая кучу параметров (выглядит как забивание гвоздей микроскопом). Но другой сервис требует действий, которые в SOAPUI можно выполнить только мануально.
Может у кого-то есть опыт в этой теме? Например с MS SOAP Toolkit (мне не удалось заставить его работать в Навижн)?
Старый 27.01.2016, 14:35   #2  
rmv is offline
rmv
Участник
 
481 / 11 (1) +
Регистрация: 15.02.2005
Я в Наве писал кодюнит обертку для SOAP, использовал для общения с Reporting Services и ECOD.
Внутри обертки тупо XML, необходимые функции веб-сервисов выставлены либо через аналогичные функции Нава, либо через общую функцию и настройки.
Вызов веб-сервиса через обертку примерно такой:

Soap.Init;
Soap.InitFunction('Render', 'rep', FALSE);
Soap.AddExecutionHeaderParam('rep:ExecutionID', RS_ExecutionID);
recRSrep.SETRANGE(recRSrep.Path,lReportName);
IF recRSrep.FIND('-') THEN
IF recRSrep.DefaultFormat<>'' THEN
Soap.AddParam('rep:Format', recRSrep.DefaultFormat)
ELSE
Soap.AddParam('rep:Format', 'EXCEL');//XLTemplate
Soap.AddParam('repeviceInfo', '<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>');
Soap.SendRequest;

Какие действия в SOAPUI можно выполнить только мануально? Это вроде-как противоречить самой идее использования SOAP
Старый 27.01.2016, 14:52   #3  
poul_and is offline
poul_and
Участник
 
56 / 12 (1) ++
Регистрация: 08.04.2003
Цитата:
Сообщение от rmv Посмотреть сообщение
Какие действия в SOAPUI можно выполнить только мануально? Это вроде-как противоречить самой идее использования SOAP
Отсылаю вебсервису логин/пароль, в ответ приходит XML файл с результатом (LoginSuccess TRUE или FALSE).
Если TRUE, то в Header-е ответа ещё есть параметр SessionID (ключ доступа), который нужно вписать в Header следующего запроса.
Сами ответы от вебсервиса могу сохранить в файл и обработать из Навижн, а вот Header-ы видны только через пользоватьльский интерфейс SOAPUI.
Старый 27.01.2016, 15:01   #4  
poul_and is offline
poul_and
Участник
 
56 / 12 (1) ++
Регистрация: 08.04.2003
Для начала попробовал использовать MS SOAP Toolkit в Навижн:


CREATE(locautSoapHttpConnector);

locautSoapHttpConnector.Property('EndPointURL', 'http://86.57.245.235/TimeTable/Service.asmx');
locautSoapHttpConnector.Connect;
locautSoapHttpConnector.Property('Timeout', 5 * 1000);
locautSoapHttpConnector.Property('SoapAction','http://webservices.belavia.by/GetAirportsList');
locautSoapHttpConnector.BeginMessage;
CREATE(locautSoapSerializer);
locautSoapSerializer.Init(locautSoapHttpConnector.InputStream);
locautSoapSerializer.StartEnvelope('SOAP','STANDARD');
locautSoapSerializer.StartBody;
locautSoapSerializer.StartElement('GetAirportsList');
locautSoapSerializer.StartElement('Language');
locautSoapSerializer.WriteString('ru');
locautSoapSerializer.EndElement;
locautSoapSerializer.EndElement;
locautSoapSerializer.EndBody;
locautSoapSerializer.EndEnvelope;
locautSoapHttpConnector.EndMessage;

CREATE(locautXmlDoc);
locautXmlDoc.load(locautSoapHttpConnector.OutputStream);
locautXmlDoc.save('c:\response.xml');

В этом виде всё работает.
А когда аналогично обращаюсь на нужный мне вебсервис - получаю ошибку:
SSL certificate common name is incorrect
Изображения
 
Старый 27.01.2016, 15:56   #5  
rmv is offline
rmv
Участник
 
481 / 11 (1) +
Регистрация: 15.02.2005
Судя по ошибке подключения по https требует, а не по http
Старый 27.01.2016, 17:16   #6  
poul_and is offline
poul_and
Участник
 
56 / 12 (1) ++
Регистрация: 08.04.2003
Цитата:
Сообщение от rmv Посмотреть сообщение
Судя по ошибке подключения по https требует, а не по http
На нужный вебсервис я по https иду


Попробовал совсем просто:


CREATE(locautXmlHttp);
locautXmlHttp.open('POST','https://193.41.33.48:443/kpsws-webapp/Login',0);
locautXmlHttp.setRequestHeader('Content-Type','application/soap+xml;charset=UTF-8');
locautXmlHttp.setRequestHeader('Host','https://193.41.33.48:443');
locautXmlHttp.send(XmlRequest);
MESSAGE('%1',locautXmlHttp.statusText);

Получаю от сервиса пустой ответ и status "Unsupported media Type"
Такую же ошибку можно получить в SOAPUI если намеренно указать неверный Content-Type.
Но тут я указываю именно нужный
Старый 27.01.2016, 18:28   #7  
Romul is offline
Romul
Участник
 
186 / 11 (1) +
Регистрация: 26.12.2007
Тут как бы несколько составляющих (в обе стороны):

1. Авторизация;
2. Создание сообщения (SOAP Envelope, XML Message);
3. Сабмит сообщения на http(s) endpoint (HttpWebRequest .NET Interop);
4. Обработка полученного от сервиса ответа (HttpWebResponse .NET Interop).

Напишите, что конкретно из этого интересует. На текущем проекте сделал кучу интеграций с использованием SOAP - все использованием стандартных .NET Interop без всяких адд-онов. Пойму, в чем именно вопрос - скину код.
Старый 28.01.2016, 09:56   #8  
poul_and is offline
poul_and
Участник
 
56 / 12 (1) ++
Регистрация: 08.04.2003
Цитата:
Сообщение от Orwell Посмотреть сообщение
Тут как бы несколько составляющих (в обе стороны):

1. Авторизация;
2. Создание сообщения (SOAP Envelope, XML Message);
3. Сабмит сообщения на http(s) endpoint (HttpWebRequest .NET Interop);
4. Обработка полученного от сервиса ответа (HttpWebResponse .NET Interop).

Напишите, что конкретно из этого интересует. На текущем проекте сделал кучу интеграций с использованием SOAP - все использованием стандартных .NET Interop без всяких адд-онов. Пойму, в чем именно вопрос - скину код.
Третий пункт

Вот этот код работает:

locautXmlHttp.open('POST','https://193.41.33.48:443/kpsws-webapp/Login', 0);
locautXmlHttp.setRequestHeader('Content-Type','application/soap+xml');
locautXmlHttp.setRequestHeader('SOAPAction','doLogin');
locautXmlHttp.send(XmlRequest);

Но, в заголовке НТТР пакета всё равно стоит "Content-Type = text/xml". Соответственно вебсервис выплёвывает ошибку
Точнее получаются две строки в заголовке "Content-Type = text/xml" и "ContentType = application/soap+xml"
Старый 28.01.2016, 12:47   #9  
poul_and is offline
poul_and
Участник
 
56 / 12 (1) ++
Регистрация: 08.04.2003
Нашел в чём проблема.
Если отсылать XML файл (XmlRequest это 'Microsoft XML, v6.0'.DOMDocument), то XmlHttp автоматом ставит Content-Type = text/xml
Видимо это нельзя отменить, необходимо в методе locautXmlHttp.send отправлять текстовую строку
Остаётся вопрос - как правильнее преоброзовать в строку большой(!) XML файл?
Старый 28.01.2016, 17:39   #10  
Romul is offline
Romul
Участник
 
186 / 11 (1) +
Регистрация: 26.12.2007
Какая версия нав? Почему не используете DotNet Interop, вместо Automation?

1. Создаете Text строку SoapEnvelope (2015 поддерживает безлимитный текст). В эту строку пихаете ваш XML.

2. Пишете функцию "открытия" веб-реквеста:

LOCAL OpenHttpWebRequest(Url : Text[250];Soap : Boolean;VAR httpWebRequest : DotNet "System.Net.HttpWebRequest")
uri := uri.Uri(Url);
httpWebRequest := httpWebRequest.CreateDefault(uri);
httpWebRequest.Method := 'POST';
httpWebRequest.Credentials := credential.DefaultNetworkCredentials;
IF Soap THEN
httpWebRequest.ContentType := 'application/soap+xml'
ELSE
httpWebRequest.ContentType := 'text/xml';

3. Далее делаете это:

OpenHttpWebRequest(HTTP_адрес_сервиса,TRUE,httpWebRequest);
streamWriter := streamWriter.StreamWriter(httpWebRequest.GetRequestStream);
streamWriter.Write(SoapEnvelope);
streamWriter.Close;
CloseHttpWebRequest(httpWebRequest);

4. Функция закрытия CloseHttpWebRequest:

httpWebResponse := httpWebRequest.GetResponse;
IF httpWebResponse.StatusDescription <> 'OK' THEN
ERROR(Text100,httpWebResponse.StatusDescription);

5. Типы переменных:
httpWebResponse DotNet System.Net.HttpWebResponse.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
httpWebRequest DotNet System.Net.HttpWebRequest.'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
streamWriter DotNet System.IO.StreamWriter.'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
uri DotNet System.Uri.'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Старый 28.01.2016, 22:13   #11  
rmv is offline
rmv
Участник
 
481 / 11 (1) +
Регистрация: 15.02.2005
Цитата:
Сообщение от poul_and Посмотреть сообщение
Нашел в чём проблема.
Если отсылать XML файл (XmlRequest это 'Microsoft XML, v6.0'.DOMDocument), то XmlHttp автоматом ставит Content-Type = text/xml
Видимо это нельзя отменить, необходимо в методе locautXmlHttp.send отправлять текстовую строку
Остаётся вопрос - как правильнее преоброзовать в строку большой(!) XML файл?
Для включения xml документов в конверт для лишенцев (Нав 5.0 и ниже) использовал xmlTextNode и функцию (ниже), но думаю проблема не в этом.
Content-Type всегда можно переопределить в хидере запроса, также попробуйте вместо XMLHTTP60 использовать ServerXMLHTTP60



AddXmlDocAsParam(lName : Text[1000];VAR lXmlDoc : Automation "'Microsoft XML, v3.0'.DOMDocument")
xmlSoapParam:=xmlDoc.createElement(lName);
xmlSoapParam:=xmlSoapFunction.appendChild(xmlSoapParam);


CREATE(lAdoStream);
lAdoStream.Open;

lXmlDoc.save(lAdoStream);

xmlDomText:=xmlSoapParam.ownerDocument.createTextNode('');

lSize:=lAdoStream.Size;
lAdoStream.Position:=0;
lAdoStream.Charset:='UTF-8';
WHILE NOT lAdoStream.EOS DO BEGIN
xmlDomText.appendData(lAdoStream.ReadText(250));
END;

xmlSoapParam.appendChild(xmlDomText);
Старый 29.01.2016, 09:50   #12  
poul_and is offline
poul_and
Участник
 
56 / 12 (1) ++
Регистрация: 08.04.2003
Цитата:
Сообщение от Orwell Посмотреть сообщение
Какая версия нав? Почему не используете DotNet Interop, вместо Automation?
Версия 2009 Classic, когда попробовал подобный пример - получил ошибку вроде "нельзя использовать DotNet Interop в C/AL коде"
Старый 29.01.2016, 17:02   #13  
Romul is offline
Romul
Участник
 
186 / 11 (1) +
Регистрация: 26.12.2007
Цитата:
Сообщение от poul_and Посмотреть сообщение
Цитата:
Сообщение от Orwell Посмотреть сообщение
Какая версия нав? Почему не используете DotNet Interop, вместо Automation?
Версия 2009 Classic, когда попробовал подобный пример - получил ошибку вроде "нельзя использовать DotNet Interop в C/AL коде"
Тогда да, без вариантов - только Automation.
Посмотрите код, что я скинул, и скоррелируйте его на свои Automation объекты.
 


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 14:38.