|
29.07.2011, 13:06 | #1 |
Участник
|
Доброе время суток ВСЕМ.
Имеется вопрос по использованию 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'); Код: 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 Набрав в 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#: Код: 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); Затем попробывали подключиться к 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); } } Вопросы: 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 |
Участник
|
Цитата:
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 |
Участник
|
Продолжение истории:
удалось добиться ответа от 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; [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; [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 в параметрах метода или можно создать еще один параметр? Как данный механизм работает? Заранее спасибо. С уважением Алексей |
|