1

I know how to send normal Text via WinHTTP 5.1 Automation and how to turn the reponse stream into an BigText object.

Now I want to send the content of a BigText via POST/PUT basicly this:

CREATE(bigText);
bigText.ADDTEXT('...');
...
CREATE(HTTP, TRUE, TRUE);
HTTP.OPEN('PUT', 'https://...', FALSE);
HTTP.SetCredentials('...', '...', 0);
HTTP.SEND(bigText);

The codeunit actually compiles and the automation object does send the request to the server, however with empty request body.

I tried to use OutStream but than the codeunit does not compile (Automation := OutStream).

I am using Dynamics NAV 2009 SP1, so no DotNet DataType available as well.

Ello
  • 907
  • 1
  • 15
  • 33
  • You can't send objects as well as streams right away. You need to serialize it first. See this answer where I'm sending file as XML node. This is not exactly what you want but you cand adapt it. https://stackoverflow.com/a/44810162/1820340 – Mak Sim Jun 29 '17 at 15:08
  • @MakSim already tried it with ADOStream : the conversion between Microsoft.Dynamics.Nav.Runtime.Nav Automation to Microsoft.Dynamics.Nav.Runtime.NavInStream is not possible when i want to pass the ADOStream to WinHTTP Send – Ello Jun 30 '17 at 09:57

1 Answers1

2

I got it to work by a stream juggle

// Variable Declaration:
// HTTP = Automation WinHTTP Services 5.1
// TempBlob = Record <TEMPORARY=YES> TempBlob
// blobOutStream = OutStream
// RequestBodyBigText = BigText
// ResponseBodyBigText = BigText
// RequestInStream = InStream
// ReponseInStream = InStream

// create WinHTTP client, force new instance, don't run locally
CREATE(HTTP, TRUE, FALSE);
HTTP.Open('PUT', '...', FALSE);
HTTP.SetCredentials('...', '....', 0);
// ...

// create InStream from BigText by the help of Temporary=YES TempBlob Record
TempBlob.INIT;
TempBlob."Blob".CREATEOUTSTREAM(blobOutStream);
// write the content of the reuquest body to the temp blob
RequestBodyBigText.WRITE(blobOutStream);
// important, calcfield the temp blob so that we can use the content
// in a new stream
TempBlob.CALCFIELDS("Blob");
TempBlob."Blob".CREATEINSTREAM(RequestInStream);

// send the stream
HTTP.Send(RequestInStream);

// timeout is in seconds
IF HTTP.WaitForResponse(30) THEN BEGIN
  ResponseInStream := HTTP.ResponseStream;
  CLEAR(ResponseBodyBigText);
  ReponseBodyBigText.READ(ResponseInStream);
END;

// now we have a big text (ResponseBodyBigText) filled with the body of the response

If you encounter encoding problems you replace the ResponsBodyBigText.READ with a convertion function and a EOS loop. If you can't use DotNet Interop DataTypes (like me) you can use the ADOStream automation with charset set to UTF-8 or you use an own written COM Object (like I did)

Ello
  • 907
  • 1
  • 15
  • 33