WinHttp.WinHttpRequest adding to the content-type WinHttp.WinHttpRequest adding to the content-type vba vba

WinHttp.WinHttpRequest adding to the content-type


I'm running into this problem, as well. It seems to be limited to the WinHttp.WinHttpRequest COM interface. There are a couple of different options to resolve this.

After some digging, I found this post from a Microsoft employee. It gives a clear explanation and recommends sending in a binary array.

If you are POSTing a string using the WinHttpRequest object, you cannot override how it encodes the string for transmission. The WinHttpRequest object will always convert the Unicode string to UTF-8.

However, note that a Unicode string that contains only 7-bit LATIN-1/ISO-8859-1 characters will remain unchanged when encoded as UTF-8 ;-) In such cases, the WinHttpRequest object does not append a "Charset=UTF-8" attribute to your Content-Type header. (And I would think that the server would assume that the POST data is ISO-8859-1.)

So, if the XML text data that you are POSTing contains LATIN-1 alphanumeric or punctuation character codes (each less than decimal 128), then all you should have to do is specify the "ISO-8859-1" charset in your Content-Type header:

WinHttpReq.SetRequestHeader "Content-Type", "application/xml;Charset=ISO-8859-1"

However, if your POST data contains 8-bit characters, then you cannot supply the data as a string to the Send method. In order to avoid the UTF-8 conversion, your application must convert the string into a byte array, and supply that instead. The WinHttpRequest object will not attempt any data conversion on a byte array.

Regards,

Stephen Sulzer

Microsoft Corporation


A second option, other than sending in a binary array, is to switch to Msxml2.XMLHTTP or Msxml2.ServerXMLHTTP. Neither of these mangle the Content-Type header. Luckily, when WinHttp.WinHttpRequest was created, Microsoft intentionally used Msxml2.XMLHTTP as a template for the interface. So, it is fairly trivial to convert the code.

Also, the Msxml2.ServerXMLHTTP COM interface uses WinHTTP internally. So, while you are losing access to some of the features that are exclusive to WinHttp.WinHttpRequest, both use the same backend.


The third option is to use ADODB.Stream. It allows you to work with an IStream, which isn't something you can normally do from VBA. The sample code below is based on the answer on the question "How to create BinaryArray in VbScript?".

' Create a Binary StreamSet objStreamBinary = CreateObject("ADODB.Stream")  objStreamBinary.Type = 1objStreamBinary.Open  ' Create a Text StreamSet objStreamText = CreateObject("ADODB.Stream")  objStreamText.Type = 2objStreamText.Open' Copy the POST data to the Text StreamobjStreamText.WriteText strRequest  objStreamText.Position = 2' Copy the Text Stream Contents to the Binary StreamobjStreamText.CopyTo objStreamBinaryobjStreamText.Close  ' Read the contents of the Binary Stream' and send it to the WinHttpRequest objectweb_Http.Send objStreamBinary.Read(-1)