Consume external NAV SOAP webservices from SaaS BC

weneed
Member Posts: 82
I am trying to consume a webservices in Business Central 14 (RTC C/AL) from Business central (BC19).
I need to send an xml file from BC19 to BC14 to obtain checks and validation.
So, I've a function in CU to do this:
This is code (from here):
Where am I wrong?
I need to send an xml file from BC19 to BC14 to obtain checks and validation.
So, I've a function in CU to do this:
[External] ValidaXML_AIFM(VAR _XMLToValidate : Text;VAR _Error : Text) RetVal : Boolean IF NOT TryValidate(XMLDoc) THEN BEGIN RetVal := FALSE; _Error := GETLASTERRORTEXT; END ELSE RetVal := TRUE;and this is sample
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <ValidaXML_AIFM xmlns="urn:microsoft-dynamics-schemas/codeunit/AIFMValidation"> <_XMLToValidate>[string]</_XMLToValidate> <_Error>[string]</_Error> </ValidaXML_AIFM> </Body> </Envelope>In BC19 executing an action user send xml file.
This is code (from here):
trigger OnAction() var FileMgnt_: Codeunit "File Management"; TempBlob_: Codeunit "Temp Blob"; InStream_: InStream; Text50000_: Label 'Select file'; FileFilterTxt_: Label 'XML File (*.xml)|*.xml'; ExtFilterTxt_: Label 'xml'; Client_: HttpClient; Content_: HttpContent; Request_: HttpRequestMessage; RequestHdr_: httpheaders; ContentHdr_: HttpHeaders; ResponseMSg_: HttpResponseMessage; Response_: HttpResponseMessage; CnvTo64_: codeunit "Base64 Convert"; Parameters_: XmlDocument; Url: Text; AuthText_: text; ResTxt_: Text; XML_String: Text; ErrorCode_: Text; begin Url := 'http://myserver.domain:7257/NAV_WS/WS/CRONUS%20Italia%20S.p.A./Codeunit/AIFMValidation'; RequestHdr_.Clear(); AuthText_ := CnvTo64_.ToBase64('MyUsername:MyPassword'); Request_.GetHeaders(RequestHdr_); RequestHdr_.Add('Accept', 'application/xml'); RequestHdr_.Add('Authorization', StrSubstNo('NTLM %1', AuthText_)); ContentHdr_.Clear(); Content_.GetHeaders(ContentHdr_); ContentHdr_.Remove('Content-Type'); ContentHdr_.Add('Content-Type', 'text/xml'); Request_.Content(Content_); FileMgnt_.BLOBImportWithFilter(TempBlob_, Text50000_, '', FileFilterTxt_, ExtFilterTxt_); TempBlob_.CreateInStream(InStream_, TextEncoding::UTF8); instream_.ReadText(XML_String); Content_.writefrom(XML_String); Request_.SetRequestUri(Url); Request_.method('POST'); if Client_.Send(Request_, Response_) then begin if Response_.IsSuccessStatusCode() then begin Response_.Content.ReadAs(ResTxt_); if XmlDocument.ReadFrom(ResTxt_, XMLDoc2_) then begin ErrorCode_ := ''; end else begin ErrorCode_ := ResTxt_; Message(ErrorCode_); end end else begin ErrorCode_ := Response_.ReasonPhrase(); error(ErrorCode_); end; end else begin if Response_.Content.ReadAs(ResTxt_) then begin ErrorCode_ := ResTxt_; Error(ErrorCode_); end else begin ErrorCode_ := Response_.ReasonPhrase; Message(ErrorCode_); end end; end;Unfortunately, executing code returns BADREQUEST error.
Where am I wrong?
0
Comments
-
Hello @weneed,
If the authentication works for you then ok , in the other hand change this codeContentHdr_.Clear(); Content_.GetHeaders(ContentHdr_); ContentHdr_.Remove('Content-Type'); ContentHdr_.Add('Content-Type', 'text/xml'); Request_.Content(Content_); FileMgnt_.BLOBImportWithFilter(TempBlob_, Text50000_, '', FileFilterTxt_, ExtFilterTxt_); TempBlob_.CreateInStream(InStream_, TextEncoding::UTF8); instream_.ReadText(XML_String); Content_.writefrom(XML_String);
Like thatContentHdr_.Clear(); Content_.GetHeaders(ContentHdr_); ContentHdr_.Remove('Content-Type'); ContentHdr_.Add('Content-Type', 'text/xml'); RequestHdr_.Add('SOAPAction', 'ValidaXML_AIFM'); FileMgnt_.BLOBImportWithFilter(TempBlob_, Text50000_, '', FileFilterTxt_, ExtFilterTxt_); TempBlob_.CreateInStream(InStream_, TextEncoding::UTF8); Content_.Writefrom(InStream); Request_.Content(Content_);
Regards0 -
Hello, unfortunately it still gives me the same error: Badrequest ..0
-
Yes Postman work.
I had to set in the header:SOAPAction urn:microsoft-dynamics-schemas/codeunit/AIFMValidationValidaXML_AIFM
and in the body:<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <ValidaXML_AIFM xmlns="urn:microsoft-dynamics-schemas/codeunit/AIFMValidation"> <_XMLToValidate></_XMLToValidate> <_Error></_Error> </ValidaXML_AIFM> </Body> </Envelope>
I miss to fill _XMLToValidate parameter to check.
Works0 -
HI @ftornero,
this is my code now:trigger OnAction() var FileMgnt_: Codeunit "File Management"; TempBlob_: Codeunit "Temp Blob"; InStream_: InStream; Text50000_: Label 'Selezionare il file da validare'; FileFilterTxt_: Label 'XML File (*.xml)|*.xml'; ExtFilterTxt_: Label 'xml'; Client_: HttpClient; Content_: HttpContent; Request_: HttpRequestMessage; RequestHdr_: httpheaders; ContentHdr_: HttpHeaders; ResponseMSg_: HttpResponseMessage; Response_: HttpResponseMessage; CnvTo64_: codeunit "Base64 Convert"; Parameters_: XmlDocument; Url: Text; AuthText_: text; ResTxt_: Text; XML_String: Text; XMLDoc2_: XmlDocument; ErrorCode_: Text; begin Url := 'http://myserver.domain:7257/NAV_WS/WS/CRONUS%20Italia%20S.p.A./Codeunit/AIFMValidation'; RequestHdr_.Clear(); AuthText_ := CnvTo64_.ToBase64('MyUser:MyPassword'); Request_.GetHeaders(RequestHdr_); RequestHdr_.Add('Accept', 'application/xml'); RequestHdr_.Add('Authorization', StrSubstNo('NTLM %1', AuthText_)); RequestHdr_.Add('SOAPAction', 'urn:microsoft-dynamics-schemas/codeunit/AIFMValidationValidaXML_AIFM'); ContentHdr_.Clear(); Content_.GetHeaders(ContentHdr_); ContentHdr_.Remove('Content-Type'); ContentHdr_.Add('Content-Type', 'text/xml'); FileMgnt_.BLOBImportWithFilter(TempBlob_, Text50000_, '', FileFilterTxt_, ExtFilterTxt_); TempBlob_.CreateInStream(InStream_, TextEncoding::UTF8); Content_.Writefrom(InStream_); Request_.Content(Content_); Request_.SetRequestUri(Url); Request_.method('POST'); if Client_.Send(Request_, Response_) then begin if Response_.IsSuccessStatusCode() then begin Response_.Content.ReadAs(ResTxt_); if XmlDocument.ReadFrom(ResTxt_, XMLDoc2_) then begin ErrorCode_ := ''; end else begin ErrorCode_ := ResTxt_; Message(ErrorCode_); end end else begin ErrorCode_ := Response_.ReasonPhrase(); error(ErrorCode_); end; end else begin if Response_.Content.ReadAs(ResTxt_) then begin ErrorCode_ := ResTxt_; Error(ErrorCode_); end else begin ErrorCode_ := Response_.ReasonPhrase; Message(ErrorCode_); end end; end;
result of the call is:
The result is the same in both cases:RequestHdr_.Add('SOAPAction', 'urn:microsoft-dynamics-schemas/codeunit/AIFMValidationValidaXML_AIFM');
RequestHdr_.Add('SOAPAction', 'urn:microsoft-dynamics-schemas/codeunit/AIFMValidation');
What I am asking is how to indicate to the ws that we want to use one method rather than another?
I think the request is incorrect. It should look like this:<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <ValidaXML_AIFM xmlns="urn:microsoft-dynamics-schemas/codeunit/AIFMValidation"> <_XMLToValidate>[string]</_XMLToValidate> <_Error>[string]</_Error> </ValidaXML_AIFM> </Body> </Envelope>
0 -
Hello @weneed,
The SOAPAction should be only the name of the procedure that you are callingRequestHdr_.Add('SOAPAction', 'ValidaXML_AIFM');
And regarding the request, is an XML that you provided in this lineFileMgnt_.BLOBImportWithFilter(TempBlob_, Text50000_, '', FileFilterTxt_, ExtFilterTxt_);
So get a correct XML file.
Regards.0 -
But hereFileMgnt_.BLOBImportWithFilter(TempBlob_, Text50000_, '', FileFilterTxt_, ExtFilterTxt_);
<_XMLToValidate></_XMLToValidate>
0 -
Hello @weneed,
Ok, that's the problem, you need to wrap this XML inside that tag, something like this:<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <m:ValidaXMLAIFM xmlns:m="urn:microsoft-dynamics-schemas/codeunit/WSBC14"> <m:_XMLToValidate> <![CDATA[ <SH> <SHTime> <SHTimeFrom>2018-07-24T00:00:00</SHTimeFrom> <SHTimeTo>2018-07-25T14:19:11</SHTimeTo> </SHTime> <SHresults> <SHresult id="267063362374320"> <SHrevsecno>06G8M</SHrevsecno> <SHownersecno>06G8M</SHownersecno> <SHrevlogin>EXT0011</SHrevlogin> <SHrevdiv>RPS TESTING PARAMETERS</SHrevdiv> <SHstatus>DS New</SHstatus> <SHrevdate>07-24-2018 17:39:06</SHrevdate> <SHname></SHname> <SHcompany>Winston</SHcompany> <SHoptid></SHoptid> </SHresult> </SHresults> </SH> ]]> </m:_XMLToValidate> <m:_Error/> </m:ValidaXMLAIFM> </Body> </Envelope>
And this new XML is the one to put in the Content.0 -
Hi, this is content that I've write in th XML:
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <ValidaXML_AIFM xmlns="urn:microsoft-dynamics-schemas/codeunit/AIFMValidation"> <_XMLToValidate>Test</_XMLToValidate> <_Error></_Error> </ValidaXML_AIFM> </Body> </Envelope>
but not work. Return always Bar request0 -
Hello @weneed
Use this one:<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <m:ValidaXML_AIFM xmlns:m="urn:microsoft-dynamics-schemas/codeunit/AIFMValidation"> <m:_XMLToValidate>Test</m:_XMLToValidate> <m:_Error></m:_Error> </m:ValidaXML_AIFM> </Body> </Envelope>
0 -
Not work. Same error..0
-
RequestHdr_.Add('SOAPAction', 'ValidaXML_AIFM');0
-
Hi @ftornero,
To understand the problem I'm trying to intercept the call with fiddler but I can't.
Every time I try fiddler it doesn't record anything ..
Fiddler is installed on the same server on which the BC service is.
Why?? If I use postman instead, it detects the call.
I also doing a different test: in a new project with target 'onPrem' I use the CU "SOAP Web Service Request Mgt." Also in this case it does not work.
This is code:var SOAP: Codeunit "SOAP Web Service Request Mgt."; url: Text; prova: Text; InStream_: InStream; OutStrem_: OutStream; TempBlob_: Codeunit "Temp Blob"; FileMgnt_: Codeunit "File Management"; Text50000_: Label 'Selezionare il file da validare'; FileFilterTxt_: Label 'XML File (*.xml)|*.xml'; ExtFilterTxt_: Label 'xml'; RespInStream: InStream; begin url := 'http://myserver.domain.local:7457/NAV_WS/WS/CRONUS%20Italia%20S.p.A./Codeunit/AIFMValidation'; FileMgnt_.BLOBImportWithFilter(TempBlob_, Text50000_, '', FileFilterTxt_, ExtFilterTxt_); TempBlob_.CreateInStream(InStream_, TextEncoding::UTF8); SOAP.SetGlobals(InStream_, url, '', ''); SOAP.SetTraceMode(true); SOAP.DisableHttpsCheck(); SOAP.SetAction('VALIDAXML_AIFM'); SOAP.SetContentType('text/xml'); SOAP.SendRequestToWebService(); Message('Done'); end;
BlobImportWithFilter read this xml file that put in request:<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <ValidaXML_AIFM xmlns="urn:microsoft-dynamics-schemas/codeunit/AIFMValidation"> <_XMLToValidate>Test</_XMLToValidate> <_Error></_Error> </ValidaXML_AIFM> </Body> </Envelope>
but server returns
Again fiddler does not record the call0
Categories
- All Categories
- 73 General
- 73 Announcements
- 66.6K Microsoft Dynamics NAV
- 18.7K NAV Three Tier
- 38.4K NAV/Navision Classic Client
- 3.6K Navision Attain
- 2.4K Navision Financials
- 116 Navision DOS
- 851 Navision e-Commerce
- 1K NAV Tips & Tricks
- 772 NAV Dutch speaking only
- 617 NAV Courses, Exams & Certification
- 2K Microsoft Dynamics-Other
- 1.5K Dynamics AX
- 320 Dynamics CRM
- 111 Dynamics GP
- 10 Dynamics SL
- 1.5K Other
- 990 SQL General
- 383 SQL Performance
- 34 SQL Tips & Tricks
- 35 Design Patterns (General & Best Practices)
- 1 Architectural Patterns
- 10 Design Patterns
- 5 Implementation Patterns
- 53 3rd Party Products, Services & Events
- 1.6K General
- 1.1K General Chat
- 1.6K Website
- 83 Testing
- 1.2K Download section
- 23 How Tos section
- 252 Feedback
- 12 NAV TechDays 2013 Sessions
- 13 NAV TechDays 2012 Sessions