简体   繁体   中英

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;
    });

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
};

It's odd that the MediaTypeHeaderValue constructor (which is what StringContent calls) doesn't accept "application/x.example.hr.employee.email+json; version=1".

However, MediaTypeHeaderValue.Parse does.

var contentType = MediaTypeHeaderValue.Parse("application/x.example.hr.employee.email+json; version=1");
var content = new StringContent(jsonEmail, Encoding.UTF8, contentType);

If you're stuck on .NET 6 and below:

var content = new StringContent(jsonEmail, Encoding.UTF8);
content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x.example.hr.employee.email+json; version=1");

See this GitHub issue for a discussion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM