Search code examples
c#httpwebrequest

Sending an Async Post WebRequest, I get a (411) Length Required


I am using the code below to post to a web site but I get a 411 error, ( The remote server returned an error: (411) Length Required).

This is the function I am using, I just removed the exception handling. I get a WebException been thrown.

private static async Task<string> PostAsync(string url, string queryString, Dictionary<string, string> headers)
{
  var webRequest = (HttpWebRequest)WebRequest.Create(url);
  webRequest.ContentType = "application/x-www-form-urlencoded";
  webRequest.Method = "POST";
  if (headers != null)
  {
    foreach (var header in headers)
    {
      webRequest.Headers.Add(header.Key, header.Value);
    }
  }

  if (!string.IsNullOrEmpty(queryString))
  {
    queryString = BuildQueryString(query);
    using (var writer = new StreamWriter(webRequest.GetRequestStream()))
    {
      writer.Write(queryString);
    }
  }

  //Make the request
  try
  {
    using (
      var webResponse = await Task<WebResponse>.Factory.FromAsync(webRequest.BeginGetResponse, webRequest.EndGetResponse, webRequest).ConfigureAwait(false))
    {
      using (var str = webResponse.GetResponseStream())
      {
        if (str != null)
        {
          using (var sr = new StreamReader(str))
          {
            return sr.ReadToEnd();
          }
        }
        return null;
      }
    }
  }
  catch (WebException wex)
  {
    // handle webexception
  }
  catch (Exception ex)
  {
    // handle webexception
  }
}

I saw on some site that adding

webRequest.ContentLength = 0;

Would work, but in some cases I get errors that the length is wrong, (so it must be something other than 0).

So my questions are, how do I set the content length properly?

And, am I sending my post requests properly? Is there another way?

Not sure if it matters, but I am using .NET 4.6, (but I can use 4.6.1 if needed).


Solution

  • The length is the length of the data you're writing to the request stream. So in this bit, set the ContentLength:

    using (var writer = new StreamWriter(webRequest.GetRequestStream()))
    {
      writer.Write(queryString);
      request.ContentLength = queryString.Length;
    }
    

    Note that you might have trouble if queryString contains unicode characters. The ContentLength indicates the number of bytes, but string.Length indicates the number of characters. Since some unicode characters take up more than one byte, there can possibly be a mismatch. There are ways to compensate if need be.

    As an alternative, you can use HttpClient instead. I haven't had to set the ContentLength manually when using it.