Friday, September 11, 2009

Salesforce WebServices SOAP Compression - Response is not well-formed XML. - '', hexadecimal value 0x1F, is an invalid character

I've been getting the following error when trying to login to the Salesforce Partner API with invalid credentials and SOAP Compression enabled. Valid credentials and subsequent API calls have been working fine.

System.InvalidOperationException: Response is not well-formed XML.
--->  System.Xml.XmlException: '', hexadecimal value 0x1F, is an invalid character.
Line 1, position 1..

The exception was coming out of the following method from the GzipWebRequest as defined here:

    public override WebResponse GetResponse()
        return new GzipWebResponse(wr.GetResponse ());

It turns out this is truly ancient .NET 1.1 code that is no longer applicable for .NET 2.0 and later projects. This has been the case for some time, I've just never gone into this part of the code base as it hasn't been failing until now.

Rather than manually accepting and decompressing the response stream we now just set EnableDecompression to true when inheriting the generated HttpWebClientProtocol (the Generated Proxy Client).

There is still the need to manually compress the outbound request. Improvements can be made here too by ditching the third party ICSharpCode.SharpZipLib.dll and using the built in System.IO.Compression.GZipStream class. There isn't anything wrong with the SharpZipLib but it's one less DLL to cart around.

See also:


  1. This comment has been removed by a blog administrator.

  2. Hello, we are having the same problem. So, did then fully removing the GetResponse() override solve the problem? What actually does the decompression then? Is it built in the HttpWebClientProtocol class? No mention of this in the documentation, as usual.

  3. Hi Pavel,
    The first thing I'd do is disable the compression to see if it gets you past the "Response is not well-formed XML" error. If the compression is causing the issue you should get a more useful error message back.

    I still have a WebRequestWrapper to add outbound compression using System.IO.Compression.GZipStream(stream, System.IO.Compression.CompressionMode.Compress). So I still override GetResponse() to use the GZipStream compression.

    The inbound compression is now being handled by setting EnableDecompression to true on the generated HttpWebClientProtocol.