You must write ContentLength bytes to the request stream before calling [Begin]GetResponse

user2516387 picture user2516387 · Sep 3, 2013 · Viewed 10.5k times · Source

Error: You must write ContentLength bytes to the request stream before calling [Begin]GetResponse.

Can anyone advise why I am getting the above error when running the following code

        Dim xml As New System.Xml.XmlDocument()

        Dim root As XmlElement
        root = xml.CreateElement("root")
        xml.AppendChild(root)

        Dim username As XmlElement
        username = xml.CreateElement("UserName")
        username.InnerText = "xxxxx"
        root.AppendChild(username)

        Dim password As XmlElement
        password = xml.CreateElement("Password")
        password.InnerText = "xxxx"
        root.AppendChild(password)

        Dim shipmenttype As XmlElement
        shipmenttype = xml.CreateElement("ShipmentType")
        shipmenttype.InnerText = "DELIVERY"
        root.AppendChild(shipmenttype)


        Dim url = "xxxxxx"
        Dim req As WebRequest = WebRequest.Create(url)
        req.Method = "POST"
        req.ContentType = "application/xml"
        req.Headers.Add("Custom: API_Method")
        req.ContentLength = xml.InnerXml.Length

        Dim newStream As Stream = req.GetRequestStream()
        xml.Save(newStream)

        Dim response As WebResponse = req.GetResponse()


        Console.Write(response.ToString())

Answer

nmaier picture nmaier · Sep 3, 2013

In short: newStream.Length != xml.InnerXml.Length.

  • First of all, XmlDocument.Save(Stream) will encode the response, which may result in a different number of bytes than are chars in the .InnerXml string.
  • .InnerXML does not necessarily contain other stuff, such as the XML preamble.

Here is a complete example. (Sorry, my VB is a bit rusty, so C# instead):

using System;
using System.IO;
using System.Net;
using System.Xml;

namespace xmlreq
{
  class Program
  {
    static void Main(string[] args)
    {
      var xml = new XmlDocument();
      var root = xml.CreateElement("root");
      xml.AppendChild(root);

      var req = WebRequest.Create("http://stackoverflow.com/");
      req.Method = "POST";
      req.ContentType = "application/xml";

      using (var ms = new MemoryStream()) {
        xml.Save(ms);
        req.ContentLength = ms.Length;
        ms.WriteTo(req.GetRequestStream());
      }
      Console.WriteLine(req.GetResponse().Headers.ToString());
    }
  }
}