16

I'm having trouble setting the Content-Type on HttpClient. I followed along this question: How do you set the Content-Type header for an HttpClient request? But still no luck.

String rcString = JsonConvert.SerializeObject(new RoadsmartChecks() { userguid = user_guid, coords = coordinates, radius = (radius * 100) + "" }, ROADSMART_JSON_FORMAT, JSONNET_SETTINGS);
HttpClient c = new HttpClient();
c.BaseAddress = new Uri(BASE_URL);
c.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json"); //Keeps returning false
c.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", hash_aes);
c.DefaultRequestHeaders.TryAddWithoutValidation("Roadsmart-app", Constant.APP_ID);
c.DefaultRequestHeaders.TryAddWithoutValidation("Roadsmart-user", user_guid);
c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, BASE_URL + URL_CHECKS + "/fetch");
req.Content = new StringContent(rcString);
await c.SendAsync(req).ContinueWith(respTask =>
{
    Debug.WriteLine("Response: {0}", respTask.Result);
});

Debugger I also tried by using the Flurl library, but it crashes when trying to add the 'Content-Type'.

misused header name content-type

So how can I force it so it really adds it? Thanks in advance.

Community
  • 1
  • 1
timr
  • 6,668
  • 7
  • 47
  • 79

3 Answers3

29

I think you should try this

req.Content = new StringContent(rcString, Encoding.UTF8, "application/json");

checkout this links :

How do you set the Content-Type header for an HttpClient request?

Edit

Remove this line c.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json"); and check

Community
  • 1
  • 1
Ajay
  • 6,418
  • 18
  • 79
  • 130
  • 1
    Now, the header is being set which is one thing. But I'm getting a 403. In Postman however the request returns json. – timr Mar 04 '15 at 10:02
  • 1
    @TimRijckaert it means it is not able to accept json result. – Ajay Mar 04 '15 at 10:19
  • 1
    Hmm, Yeah I see the problem now. One of my headers has "\"value"\". So I need to unescape the string. – timr Mar 04 '15 at 10:21
3

UPDATE: See new answer for non-default content types

With Flurl you shouldn't need to set Content-Type to application/json for methods like PostJsonAsync. This is the default content type in this case and it will get set for you.

Todd Menier
  • 37,557
  • 17
  • 150
  • 173
  • 2
    Well it seemed a parameter of my was wrongly converted so I'll give Flurl another try as it simplifed the code much. Thanks – timr Mar 04 '15 at 13:21
  • Until you encounter an api that actually requires you to set a Content-Type header on the POST request :-/ – quentin-starin Jan 18 '16 at 07:54
  • @qes are you saying you're posting JSON formatted data and yet the API requires you set a Content-Type _other_ than application/json? – Todd Menier Jan 18 '16 at 14:44
  • @ToddMenier It's a soap xml api for flight data and I have to set it to text/xml while post'ing the xml request body or else the api returns a 415. I may have missed it, but I wasn't able to figure out how to get Flurl to do that. Ajay's solution above using HttpClient works for me, though. – quentin-starin Jan 19 '16 at 16:49
  • @qes did you try `.WithHeader("Content-Type", "text/xml")` in the flurl call? – Todd Menier Jan 19 '16 at 18:19
  • 1
    @ToddMenier Yes, it results in an invalid operation exception: Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects. It comes from System.Net.Http.Headers.HttpHeaders.Add(...) – quentin-starin Jan 25 '16 at 20:51
2

The latest and greatest answer to this with Flurl is to upgrade. 2.0 introduces several enhancements in the headers dept:

  1. They're no longer validated. Flurl now uses TryAddWithoutValidation under the hood, so you'll never get the "misused header name" error with the WithHeader(s) methods. (I always found that validation behavior to be a bit overprotective.)

  2. In a fluent call they're set at the individual request level rather than the FlurlClient level, so you won't run into concurrency issues when reusing the client.

  3. Since hyphens are common in header names but not allowed in C# identifiers, there's a new convention where underscores are converted to hyphens so you don't have to give up object notation when specifying multiple:

    url.WithHeaders(new { Content_Type = "foo", ... }
    
Todd Menier
  • 37,557
  • 17
  • 150
  • 173