views:

67

answers:

3

This is driving me nuts:

    WebRequest request = WebRequest.Create(url);
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = Encoding.UTF8.GetByteCount(data);
    Stream reqs = request.GetRequestStream();
    StreamWriter stOut = new StreamWriter(reqs, Encoding.UTF8);
    stOut.Write(data);
    stOut.Flush();

I get an exception that I've run out of bytes in the stream...but I've used the same encoding to get the byte count!

Using ASCII this doesn't fail. Is this because of the UTF-8 BOM that Windows likes to add in?

+3  A: 

This is probably the BOM; try using an explicit encoding without a BOM:

Encoding enc = new UTF8Encoding(false);
...
request.ContentLength = enc.GetByteCount(data);
...
StreamWriter stOut = new StreamWriter(reqs, enc);

Even easier; switch to WebClient instead and of trying to handle it all yourself; it is very easy to post a form with this:

    using (var client = new WebClient())
    {
        var data = new NameValueCollection();
        data["foo"] = "123";
        data["bar"] = "456";
        byte[] resp = client.UploadValues(address, data);
    }

Or with the code from here:

  byte[] resp = client.Post(address, new {foo = 123, bar = 546});
Marc Gravell
The easiest thing to do actually is skip the content-length assignment...but it's definitely due to the BOM.
Broam
Using an explicit encoding object worked.
Broam
+1  A: 

You can also try something like this:

byte[] bytes = Encoding.UTF8.GetBytes(data);

request.ContentLength = bytes.Length;
request.GetRequestStream().Write(bytes, 0, bytes.Length);
João Angelo
+1  A: 

Don't forget to actually URL-encode the data, like you promised in the ContentType. It's a one-liner:

byte[] bytes = System.Web.HttpUtility.UrlEncodeToBytes(data, Encoding.UTF8);
Hans Passant