Asp.Net core HttpClient gets response 411 length required error

Viewed 4648

I am trying to make an service that posts some data to an API Endpoint using C# HttpClient. The code is as follows.

public class HttpClientService : IHttpClientService
{
    static HttpClient client = new HttpClient();

    public HttpClientService()
    {
        client.BaseAddress = new Uri("http://xx.xx.xx.xx/");
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }

    public async Task<Uri> MakeLogEntry(CnsLog log)
    {
        HttpResponseMessage response = await client.PostAsJsonAsync("api/logs", log);
        return response.Headers.Location;
    }

}

The problem is that the end point returns error 411 Length Required. I have found that this is because my request doesn't have the content-length header set, which I found to be true when I inspected the request using Fiddler.

I have tried to set the content length header on the client in the constructor but the code doesn't compile after that. I'm stuck and would appreciate any help. Thanks

2 Answers

You don't want to set the Content-Length header on the client, especially since it's a static instance. You want to set it on the individual request.

PostAsJsonAsync is a nice shortcut that builds the HttpContent from a poco, builds the HttpRequestMessage from that content, and sends the POST request. Handy, but all that abstraction doesn't give you the opportunity to set request-level headers. So, you need to do a little more work to build/send the request:

var json = JsonConvert.SerializeObject(log);
var content = new StringContent(json, Encoding.UTF8, "application/json");
content.Headers.ContentLength = json.Length;
var response = await client.PostAsync("api/logs", content);

Alternately you can use HttpWebRequest.

byte[] postBytes = Encoding.ASCII.GetBytes(log);
request.ContentLength = postBytes.Length;

Example of HttpWebRequest is as below:

ASCIIEncoding encoder = new ASCIIEncoding();
byte[] data = encoder.GetBytes(serializedObject); // a json object, or xml, whatever...

HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = data.Length;
request.Expect = "application/json";

request.GetRequestStream().Write(data, 0, data.Length);

HttpWebResponse response = request.GetResponse() as HttpWebResponse;
Related