Search code examples
c#.net-coreasp.net-core-webapihttpclientcontent-type

How to set "custom" Content-Type of an HttpClient request in DOT NET CORE?


I'm trying to set Content-Type as "application/x.example.hr.employee.email+json;version=1" of an HttpClient request as required by the API I am calling. The API is of type GET and accepts a JSON body (containing list of emails).

I'm successfully able to set Accept header to "application/x.example.hr.employee+json;version=1". In this case, both - Accept and Content-Type need to be set as mentioned, otherwise API throws a error of 400 (Bad request). I tried How do you set the Content-Type header for an HttpClient request? and several other options but getting run time error when I try to set Content-Type other than "application/json".

This type needs to be applied on the request content but not in the header Content-Type. Below is one of the code snippet I tried:

_httpClient.BaseAddress = new Uri("http://example.com/");
_httpClient.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/x.example.hr.employee+json;version=1");
//_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/x.example.hr.employee.email+json;version=1"); // Throws exception

List<string> strEmail = new List<string>
{
     employeeEmail
};
var jsonEmail = JsonConvert.SerializeObject(strEmail);

var request = new HttpRequestMessage()
{
    Method = HttpMethod.Get,
    RequestUri = new Uri("http://example.com/employees"),
    Content = new StringContent(jsonEmail, Encoding.UTF8, "application/x.example.hr.employee.email+json;version=1")
};

//var response = _httpClient.SendAsync(request).ConfigureAwait(false);

await _httpClient.SendAsync(request)
    .ContinueWith(responseTask =>
    {
        var response = responseTask;
    });

Solution

  • For a reason that don't fully understand, the "application/x.example.hr.employee.email+json;version=1" media type is not correctly parsed whenever you build a StringContent (or actually a MediaTypeHeaderValue).

    I did find a workaround for this:

    List<string> strEmail = new List<string> {
        employeeEmail
    };
    var jsonEmail = JsonConvert.SerializeObject(strEmail);
    var content = new StringContent(jsonEmail, Encoding.UTF8);
    content.Headers.ContentType = new MediaTypeHeaderValue("application/x.example.hr.employee.email+json");
    content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("version", "1"));
    
    var request = new HttpRequestMessage()
    {
        Method = HttpMethod.Get,
        RequestUri = new Uri("http://example.com/employees"),
        Content = content
    };