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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 29.07.2011, 13:06   #1  
AS850 is offline
AS850
Участник
 
13 / 10 (1) +
Регистрация: 14.08.2009
Доброе время суток ВСЕМ.

Имеется вопрос по использованию Web сервисов в NAV2009 R2. Сразу оговорюсь, что я не специалист в .Net и web сервисах. Авторы кода написанного на С# - коллеги.

Задача:
Интегрировать NAV с некой системой «Х». Система «Х» посылает запрос (xmlmsg) к NAV. NAV анализирует полученный запрос и отвечает на него. Запрос и ответ имеют XML структуру.
К системе «Х» прилагается тестовый Web сервис, в котором реализованы все необходимые методы. Именно этот сервис должен быть заменен на сервис NAV.

Тестовая среда:
Система»Х» <--------> Тестовый сервис «Х»

Требуется создать (не хотелось бы добавлять в эту цепочку дополнительных посредников):
Система»Х» <--------> Сервис „MS DynNAV Business Web Services” <--------> MS Dyn NAV 2009

Сделано:
Создан Codeunit, в котором есть процедура AliveTest (на самом деле есть еще процедура GetEntry):

Код:
AliveTest(VAR AliveTestResponse : XMLport "X AliveTest")
CLEAR(AliveTestResponse);
AliveTestResponse.SetWebServiceCode('BusinessPartnerData');
Структура XML порта „X AliveTest”:
Код:
Node Name		Node Type	Source Type	Data Source
MESSAGE		        Element	        Text	<MESSAGE>
  DTD			Attribute	Text	MSG_DTD
  VERSION		Attribute	Text	MSG_VERSION
  RESULT		Element	        Text	<RESULT>
    RESPONSE		Element	        Text	<RESPONSE>
      NAME		Attribute	Text	RESPONSE_NAME
      DTD		Attribute	Text	RESPONSE_DTD
      VERSION		Attribute	Text	RESPONSE_VERSION
      ID		Attribute	Text	RESPONSE_ID
      DATA		Element	        Text	<DATA>
        APPLICATION	Element	        Text	<APPLICATION>
          HOSTNAME	Attribute	Text	APPL_HOSTNAME
          NAME	        Attribute	Text	APPL_NAME
          VERSION	Attribute	Text	APPL_VERSION
          VENDOR	Attribute	Text	APPL_VENDOR
        SERVICE    	Element	        Table	CounterForService(Integer)
          NAME	        Attribute	Text	SERVICE_NAME
          DTD		Attribute	Text	SERVICE_DTD
          VERSION	Attribute	Text	SERVICE_VERSION
          METHOD	Element  	Table	CounterForMethod(Integer)
            METHOD	Attribute	Text	METHOD_NAME
            VERSION	Attribute	Text	METHOD_VERSION
Codeunit опубликован как web сервис „BusinessPartnerData”.

Набрав в IE запрос http://localhost:7047/DynamicsNAV/WS/Services получаем ответ:
[xml]
<discovery xmlns="http://schemas.xmlsoap.org/disco/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
...
<contractRef ref="http://localhost:7047/DynamicsNAV/WS/Codeunit/BusinessPartnerData" xmlns="http://schemas.xmlsoap.org/disco/scl/" />
...
</discovery>
[/xml]

Набрав в IE запрос http://localhost:7047/DynamicsNAV/WS...essPartnerData получаем ответ:
[xml]
<definitions targetNamespace="urn:microsoft-dynamics-schemas/codeunit/BusinessPartnerData" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="urn:microsoft-dynamics-schemas/codeunit/BusinessPartnerData">
<types>
<schema elementFormDefault="qualified" targetNamespace="urn:microsoft-dynamics-nav/xmlports/x50000" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="urn:microsoft-dynamics-nav/xmlports/x50000">
<complexType name="APPLICATION" mixed="true">
<sequence />
<attribute name="HOSTNAME" type="string" use="required" />
<attribute name="NAME" type="string" use="required" />
<attribute name="VERSION" type="string" use="required" />
<attribute name="VENDOR" type="string" use="required" />
</complexType>
<complexType name="METHOD">
<sequence />
<attribute name="METHOD" type="string" use="required" />
<attribute name="VERSION" type="string" use="required" />
</complexType>
<complexType name="SERVICE">
<sequence>
<element minOccurs="1" maxOccurs="unbounded" name="METHOD" type="tns:METHOD" />
</sequence>
<attribute name="NAME" type="string" use="required" />
<attribute name="DTD" type="string" use="required" />
<attribute name="VERSION" type="string" use="required" />
</complexType>
<complexType name="DATA" mixed="true">
<sequence>
<element minOccurs="1" maxOccurs="unbounded" name="APPLICATION" type="tns:APPLICATION" />
<element minOccurs="1" maxOccurs="unbounded" name="SERVICE" type="tns:SERVICE" />
</sequence>
</complexType>
<complexType name="RESPONSE" mixed="true">
<sequence>
<element minOccurs="1" maxOccurs="unbounded" name="DATA" type="tnsATA" />
</sequence>
<attribute name="NAME" type="string" use="required" />
<attribute name="DTD" type="string" use="required" />
<attribute name="VERSION" type="string" use="required" />
<attribute name="ID" type="string" use="required" />
</complexType>
<complexType name="RESULT" mixed="true">
<sequence>
<element minOccurs="1" maxOccurs="unbounded" name="RESPONSE" type="tns:RESPONSE" />
</sequence>
</complexType>
<complexType name="MESSAGE" mixed="true">
<sequence>
<element minOccurs="1" maxOccurs="unbounded" name="RESULT" type="tns:RESULT" />
</sequence>
<attribute name="DTD" type="string" use="required" />
<attribute name="VERSION" type="string" use="required" />
</complexType>
<element name="MESSAGE" type="tns:MESSAGE" />
</schema>
<schema elementFormDefault="qualified" targetNamespace="urn:microsoft-dynamics-nav/xmlports/x50002" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="urn:microsoft-dynamics-nav/xmlports/x50002">
<complexType name="NAME" mixed="true">
<sequence />
<attribute name="TYPE" type="string" use="required" />
</complexType>
<complexType name="BUSINESS_PARTNER">
<sequence>
<element minOccurs="1" maxOccurs="1" name="ACCOUNT_NO" type="string" />
<element minOccurs="1" maxOccurs="unbounded" name="MATCHCODE" type="string" />
<element minOccurs="1" maxOccurs="unbounded" name="COURTESY_TITLE" type="string" />
<element minOccurs="1" maxOccurs="1" name="NAME" type="tns:NAME" />
<element minOccurs="1" maxOccurs="1" name="ADDRESS" type="string" />
<element minOccurs="1" maxOccurs="1" name="ZIP" type="string" />
<element minOccurs="1" maxOccurs="1" name="CITY" type="string" />
<element minOccurs="1" maxOccurs="1" name="COUNTRY" type="string" />
</sequence>
</complexType>
<complexType name="DATA" mixed="true">
<sequence>
<element minOccurs="1" maxOccurs="unbounded" name="BUSINESS_PARTNER" type="tns:BUSINESS_PARTNER" />
</sequence>
</complexType>
<complexType name="RESPONSE" mixed="true">
<sequence>
<element minOccurs="1" maxOccurs="unbounded" name="DATA" type="tnsATA" />
</sequence>
<attribute name="DTD" type="string" use="required" />
<attribute name="ID" type="string" use="required" />
<attribute name="NAME" type="string" use="required" />
</complexType>
<complexType name="RESULT" mixed="true">
<sequence>
<element minOccurs="1" maxOccurs="unbounded" name="RESPONSE" type="tns:RESPONSE" />
</sequence>
</complexType>
<complexType name="MESSAGE" mixed="true">
<sequence>
<element minOccurs="1" maxOccurs="unbounded" name="RESULT" type="tns:RESULT" />
</sequence>
<attribute name="DTD" type="string" use="required" />
<attribute name="VERSION" type="string" use="required" />
</complexType>
<element name="MESSAGE" type="tns:MESSAGE" />
</schema>
<schema elementFormDefault="qualified" targetNamespace="urn:microsoft-dynamics-schemas/codeunit/BusinessPartnerData" xmlns="http://www.w3.org/2001/XMLSchema">
<element name="AliveTest">
<complexType>
<sequence>
<element minOccurs="1" maxOccurs="1" name="aliveTestResponse" type="q1:MESSAGE" xmlns:q1="urn:microsoft-dynamics-nav/xmlports/x50000" />
</sequence>
</complexType>
</element>
<element name="AliveTest_Result">
<complexType>
<sequence>
<element minOccurs="1" maxOccurs="1" name="aliveTestResponse" type="q2:MESSAGE" xmlns:q2="urn:microsoft-dynamics-nav/xmlports/x50000" />
</sequence>
</complexType>
</element>
<element name="GetEntry">
<complexType>
<sequence>
<element minOccurs="1" maxOccurs="1" name="xMLBusinessPartnerData" type="q3:MESSAGE" xmlns:q3="urn:microsoft-dynamics-nav/xmlports/x50002" />
</sequence>
</complexType>
</element>
<element name="GetEntry_Result">
<complexType>
<sequence>
<element minOccurs="1" maxOccurs="1" name="xMLBusinessPartnerData" type="q4:MESSAGE" xmlns:q4="urn:microsoft-dynamics-nav/xmlports/x50002" />
</sequence>
</complexType>
</element>
</schema>
</types>
<message name="AliveTest">
<part name="parameters" element="tns:AliveTest" />
</message>
<message name="AliveTest_Result">
<part name="parameters" element="tns:AliveTest_Result" />
</message>
<message name="GetEntry">
<part name="parameters" element="tns:GetEntry" />
</message>
<message name="GetEntry_Result">
<part name="parameters" element="tns:GetEntry_Result" />
</message>
<portType name="BusinessPartnerData_Port">
<operation name="AliveTest">
<input name="AliveTest" message="tns:AliveTest" />
<output name="AliveTest_Result" message="tns:AliveTest_Result" />
</operation>
<operation name="GetEntry">
<input name="GetEntry" message="tns:GetEntry" />
<output name="GetEntry_Result" message="tns:GetEntry_Result" />
</operation>
</portType>
<binding name="BusinessPartnerData_Binding" type="tns:BusinessPartnerData_Port">
<binding transport="http://schemas.xmlsoap.org/soap/http" xmlns="http://schemas.xmlsoap.org/wsdl/soap/" />
<operation name="AliveTest">
<operation soapAction="urn:microsoft-dynamics-schemas/codeunit/BusinessPartnerData:AliveTest" style="document" xmlns="http://schemas.xmlsoap.org/wsdl/soap/" />
<input name="AliveTest">
<body use="literal" xmlns="http://schemas.xmlsoap.org/wsdl/soap/" />
</input>
<output name="AliveTest_Result">
<body use="literal" xmlns="http://schemas.xmlsoap.org/wsdl/soap/" />
</output>
</operation>
<operation name="GetEntry">
<operation soapAction="urn:microsoft-dynamics-schemas/codeunit/BusinessPartnerData:GetEntry" style="document" xmlns="http://schemas.xmlsoap.org/wsdl/soap/" />
<input name="GetEntry">
<body use="literal" xmlns="http://schemas.xmlsoap.org/wsdl/soap/" />
</input>
<output name="GetEntry_Result">
<body use="literal" xmlns="http://schemas.xmlsoap.org/wsdl/soap/" />
</output>
</operation>
</binding>
<service name="BusinessPartnerData">
<port name="BusinessPartnerData_Port" binding="tns:BusinessPartnerData_Binding">
<address location="http://localhost:7047/DynamicsNAV/WS/DEMO/Codeunit/BusinessPartnerData" xmlns="http://schemas.xmlsoap.org/wsdl/soap/" />
</port>
</service>
</definitions>
[/xml]

Попытка переключить систему «Х» с тестового сервиса «Х» на NAV сервис, посредством замены адреса в настройках системы "Х" не удалась. Именно так система "Х" знает к какому сервису обращаться.
Сообщение об ошибке:
Код:
The Service is not available
java.io.IOException: Server returned HTTP response code: 401 for URL: http://localhost:7047/DynamicsNAV/WS...essPartnerData
Detailed response from http://localhost:7047/DynamicsNAV/WS...ssPartnerData:

HTTP/1.1 401 Unauthorized 
Content-Length: 0 
Server: Microsoft-HTTPAPI/1.0 
WWW-Authenticate: Negotiate
Поэтому, попробывали создать программу на C#, для тестирования.
Сначала попробывали подключиться с тестовому сервису системы «Х».
Код на C#:
Код:
var content = File.ReadAllText(@"e:\xml\query3.txt").Trim();
var address = "http://localhost:6700/businesspartnerdata";
       
var client = new WebClient();
client.Credentials = CredentialCache.DefaultNetworkCredentials;
client.Headers.Add(HttpRequestHeader.ContentType, "text/xml");
            
client.Headers.Add("SOAPAction", "urn://localhost:6700/businesspartnerdata:AliveTest");
            
var result = client.UploadString(address, content);

textBox1.Text = result;
Полученный ответ от тестового сервиса «Х»:
[xml]
?xml version="1.0" encoding="UTF-8"?>
<MESSAGE DTD="XMLMSG" VERSION="1.4.0.0">
<RESULT>
<RESPONSE DTD="" ID="20031107102901" NAME="AliveTest" VERSION="">
<DATA>
<APPLICATION HOSTNAME="lae-vp" NAME="X" VENDOR="Vendor" VERSION="2.0.1.2"/>
<SERVICE DTD="BusinessPartnerData" NAME="BusinessPartnerData" VERSION="1.0.0.0">
<METHOD VERSION="1.0.0.0">GetEntry</METHOD>
<METHOD VERSION="1.0.0.0">UpdateEntry</METHOD>
<METHOD VERSION="1.0.0.0">AliveTest</METHOD>
<METHOD VERSION="1.0.0.0">NewEntry</METHOD>
</SERVICE>
</DATA>
</RESPONSE>
</RESULT>
</MESSAGE>
[/xml]

Затем попробывали аналогично подключиться с NAV сервису.
Код на C# (вариант 1):
Код:
string content = File.ReadAllText(@"e:\xml\query3.txt").Trim();
var address = "http://localhost:7047/DynamicsNAV/WS/DEMO/Codeunit/BusinessPartnerData";
            
var client = new WebClient();
client.Credentials = CredentialCache.DefaultNetworkCredentials;
client.Headers.Add(HttpRequestHeader.ContentType, "xmlmsg/http");
client.Headers.Add("SOAPAction", "urn:microsoft-dynamics-schemas/codeunit/BusinessPartnerData:AliveTest");
                        
var result = client.UploadString(address, content);

textBox1.Text = result;
При выполнении строки
Код:
var result = client.UploadString(address, content);
получаем ошибку 500 (детали ошибки надо смотреть в файле error.log, но такого файла не нашел).

Затем попробывали подключиться к NAV сервису другим способом.
Код на C# (вариант 2) :
Код:
(BPDRef  as WebReference)

var service = new BPDRef.BusinessPartnerData();
service.Url = "http://localhost:7047/DynamicsNAV/WS/DEMO/Codeunit/BusinessPartnerData";
service.UseDefaultCredentials = true;
var ServiceReply = new BPDRef.MESSAGE();

service.AliveTest(ref ServiceReply);

textBox1.Text = string.Empty;

if (ServiceReply != null && ServiceReply.RESULT != null)
{
     foreach (var R in ServiceReply.RESULT)
     {
          textBox1.Text += "\n\r";
          textBox1.Text += String.Format("{0}", ServiceReply.RESULT);
     }
}
Код 2-го варианта работает и возращает значения.

Вопросы:
1. Возможно ли подключиться к NAV используя вариант 1? Если, да, то каким образом?

2. Не требуется ли некий конвертор в цепочке:
Система»Х» <--------> Конвертор? <--------> Сервис „MS DynNAV Business Web Services” <--------> MS Dyn NAV 2009

3. Запрос от системы «Х» упакован в xml:
[xml]
<?xml version="1.0" encoding="UTF-8"?>
<MESSAGE DTD="XMLMSG" VERSION="1.4.0.0">
<COMMAND>
<REQUEST NAME="AliveTest" DTD="" VERSION="" ID="20031107102901"/>
</COMMAND>
</MESSAGE>
[/xml]
Этот xml надо проанализировать и подготовить ответ. Ответ возращается, используя xml порт, который NAV сам запускает на экпорт. А как быть с запросом? Еще один параметр без VAR или же использовать тот же самый xml порт и NAV запустит его на импорт?

4. Может надо решать эту задачу вообще другим способом?

P.S. есть возможность задавать вопросы разработчику системы «Х». Только не знаю, что спросить...

С уважением и надеждой
Алексей
Старый 29.07.2011, 14:06   #2  
.Quattro. is offline
.Quattro.
Участник
Лучший по профессии 2009
 
194 / 22 (1) +++
Регистрация: 22.05.2006
Цитата:
The Service is not available
java.io.IOException: Server returned HTTP response code: 401 for URL: http://localhost:7047/DynamicsNAV/WS...essPartnerData
Detailed response from http://localhost:7047/DynamicsNAV/WS...ssPartnerData:

HTTP/1.1 401 Unauthorized
Content-Length: 0
Server: Microsoft-HTTPAPI/1.0
WWW-Authenticate: Negotiate
Вы не прошли авторизацию на сервере, судя по ошибке.
Копайте в этом направлении.
Старый 31.07.2011, 21:16   #3  
AS850 is offline
AS850
Участник
 
13 / 10 (1) +
Регистрация: 14.08.2009
Продолжение истории:

удалось добиться ответа от NAV, используя 1-й вариант кода. Вскрылась одна проблема. Приведу код на С#, содержание запроса и ответа сервисов: тестового и NAV сервиса.

Тестовый сервис:

Код на C#:
Код:
var content = File.ReadAllText(@"e:\xml\test-service.txt").Trim();
var address = "http://localhost:6700/businesspartnerdata";
   
var client = new WebClient();
client.Credentials = CredentialCache.DefaultNetworkCredentials;
client.Headers.Add(HttpRequestHeader.ContentType, "xmlmsg/http");
client.Headers.Add("SOAPAction", "urn://localhost:6700/businesspartnerdata:AliveTest");

var result = client.UploadString(address, content);

textBox1.Text = result;
Содержимое файла test-service.xml - запрос:
[xml]
<?xml version="1.0" encoding="UTF-8"?>
<MESSAGE DTD="XMLMSG" VERSION="1.4.0.0">
<COMMAND>
<REQUEST NAME="AliveTest" DTD="" VERSION="" ID="20031107102901"/>
</COMMAND>
</MESSAGE>
[/xml]

Ответ полученный от тестового сервиса системы "Х":
[xml]
<?xml version="1.0" encoding="UTF-8"?>
<MESSAGE DTD="XMLMSG" VERSION="1.4.0.0">
<RESULT>
<RESPONSE DTD="" ID="20031107102901" NAME="AliveTest" VERSION="">
<DATA>
<APPLICATION HOSTNAME="lae-vp" NAME="X" VENDOR="Vendor" VERSION="2.0.1.2"/>
<SERVICE DTD="BusinessPartnerData" NAME="BusinessPartnerData" VERSION="1.0.0.0">
<METHOD VERSION="1.0.0.0">GetEntry</METHOD>
<METHOD VERSION="1.0.0.0">UpdateEntry</METHOD>
<METHOD VERSION="1.0.0.0">AliveTest</METHOD>
<METHOD VERSION="1.0.0.0">Subscription</METHOD>
<METHOD VERSION="1.0.0.0">NewEntry</METHOD>
</SERVICE>
</DATA>
</RESPONSE>
</RESULT>
</MESSAGE>
[/xml]

NAV сервис:

Код на C#:
Код:
var content = File.ReadAllText(@"e:\xml\nav-service.txt").Trim();
var address = "http://localhost::7047/DynamicsNAV/WS/DEMO/Codeunit/BusinessPartnerData";
   
var client = new WebClient();
client.Credentials = CredentialCache.DefaultNetworkCredentials;
client.Headers.Add(HttpRequestHeader.ContentType, "text/xml");
client.Headers.Add("SOAPAction", "urn://localhost:7047/DynamicsNAV/WS/DEMO/Codeunit/BusinessPartnerData:AliveTest");

var result = client.UploadString(address, content);

textBox1.Text = result;
Содержимое файла nav-service.xml - запрос:
[xml]
<?xml version="1.0" encoding="utf-8"?><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>
<AliveTest xmlns="urn:microsoft-dynamics-schemas/codeunit/BusinessPartnerData"><aliveTestResponse /></AliveTest>
</soap:Body></soap:Envelope>
[/xml]

Ответ полученный от NAV сервиса:
[xml]
<Soap:Envelope xmlns:Soap="http://schemas.xmlsoap.org/soap/envelope/">
<Soap:Body>
<AliveTest_Result xmlns="urn:microsoft-dynamics-schemas/codeunit/BusinessPartnerData">
<aliveTestResponse DTD="XMLMSG" VERSION="1.4.0.0">
<RESULT xmlns="urn:microsoft-dynamics-nav/xmlports/x50000">
<RESPONSE NAME="AliveTest" DTD="BusinessPartnerData" VERSION="1.4.0.0" ID="1">
<DATA>
<APPLICATION HOSTNAME="lae-vp" NAME="NAV" VERSION="6.2.0.1" VENDOR="NAV"/>
<SERVICE NAME="BusinessPartnerData" DTD="BusinessPartnerData" VERSION="0.0.0.1">
<METHOD METHOD="AliveTest" VERSION="0.0.0.1"/>
<METHOD METHOD="GetEntry" VERSION="0.0.0.1"/>
<METHOD METHOD="NewEntry" VERSION="0.0.0.1"/>
<METHOD METHOD="UpdateEntry" VERSION="0.0.0.1"/>
</SERVICE>
</DATA>
</RESPONSE>
</RESULT>
</aliveTestResponse>
</AliveTest_Result>
</Soap:Body>
</Soap:Envelope>
[/xml]

Как видно код отличается одной строчкой:
Код:
client.Headers.Add(HttpRequestHeader.ContentType, "xmlmsg/http");
и
Код:
client.Headers.Add(HttpRequestHeader.ContentType, "text/xml");
Еще отличаются форматы запросов и ответов.

Вопросы:
1. Можно ли настроить NAV принимать и отвечать в том же формате, что и тестовый сервис системы "Х"?
2. Как передать xml запрос в NAV? Через тот же XMLport в параметрах метода или можно создать еще один параметр? Как данный механизм работает?


Заранее спасибо.

С уважением
Алексей
 


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

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

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