Доброе время суток ВСЕМ.
Имеется вопрос по использованию 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="tns
ATA" />
</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="tns
ATA" />
</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 сервис, посредством замены адреса в настройках системы "Х" не удалась. Именно так система "Х" знает к какому сервису обращаться.
Сообщение об ошибке:
Поэтому, попробывали создать программу на 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. есть возможность задавать вопросы разработчику системы «Х». Только не знаю, что спросить...
С уважением и надеждой
Алексей