How to remove charset = utf8 from the Content-Type header generated by HttpClient.PostAsJsonAsync ()?

I have a problem with HttpClient.PostAsJsonAsync ()

In addition to “application / json” in the “Content-Type” header, the method also adds “charset = utf-8”

so the title is as follows:

Content-Type: application / json; encoding = UTF-8

While ASP.NET WebAPI does not have any problems with this header, I found that other WebAPIs that I work with as a client do not accept a request with this header, unless it is an application / json.

Is there a way to remove "charset = utf-8" from the Content-Type when using PostAsJsonAsync () or use another method?

SOLUTION: Loans

using System.Net.Http.Headers; public class NoCharSetJsonMediaTypeFormatter : JsonMediaTypeFormatter { public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) { base.SetDefaultContentHeaders(type, headers, mediaType); headers.ContentType.CharSet = ""; } } public static class HttpClientExtensions { public static async Task<HttpResponseMessage> PostAsJsonWithNoCharSetAsync<T>(this HttpClient client, string requestUri, T value, CancellationToken cancellationToken) { return await client.PostAsync(requestUri, value, new NoCharSetJsonMediaTypeFormatter(), cancellationToken); } public static async Task<HttpResponseMessage> PostAsJsonWithNoCharSetAsync<T>(this HttpClient client, string requestUri, T value) { return await client.PostAsync(requestUri, value, new NoCharSetJsonMediaTypeFormatter()); } } 
+7
json asp.net-web-api utf-8
source share
3 answers

You can get JsonMediaTypeFormatter and override SetDefaultContentHeaders.

Call base.SetDefaultContentHeaders() and then clear headers.ContentType.CharSet

then write your own extension method based on the following code:

 public static Task<HttpResponseMessage> PostAsJsonAsync<T>(this HttpClient client, string requestUri, T value, CancellationToken cancellationToken) { return client.PostAsync(requestUri, value, new JsonMediaTypeFormatter(), cancellationToken); } 

Essentially something like:

 public static Task<HttpResponseMessage> PostAsJsonWithNoCharSetAsync<T>(this HttpClient client, string requestUri, T value, CancellatioNToken cancellationToken) { return client.PostAsync(requestUri, value, new NoCharSetJsonMediaTypeFormatter(), cancellationToken); } 
+4
source

For more direct control over the payload you are passing, you can create HttpContent derived classes instead of passing your object to the ObjectContent class, which then passes the streams to the Formatter class.

The JsonContent class, which supports reading and writing, looks like this:

 public class JsonContent : HttpContent { private readonly Stream _inboundStream; private readonly JToken _value; public JsonContent(JToken value) { _value = value; Headers.ContentType = new MediaTypeHeaderValue("application/json"); } public JsonContent(Stream inboundStream) { _inboundStream = inboundStream; } public async Task<JToken> ReadAsJTokenAsync() { return _value ?? JToken.Parse(await ReadAsStringAsync()); } protected async override Task<Stream> CreateContentReadStreamAsync() { return _inboundStream; } protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) { if (_value != null) { var jw = new JsonTextWriter(new StreamWriter(stream)) {Formatting = Formatting.Indented}; _value.WriteTo(jw); jw.Flush(); } else if (_inboundStream != null) { return _inboundStream.CopyToAsync(stream); } return Task.FromResult<object>(null); } protected override bool TryComputeLength(out long length) { length = -1; return false; } protected override void Dispose(bool disposing) { if (disposing) { _inboundStream.Dispose(); } base.Dispose(disposing); } } 

Once you get this class,

 var content = new JsonContent(myObject); _httpClient.PostAsync(uri,content); 

If you need to change the content title, you can do it manually before submitting a request. And if you need to bother with any request header, you use SendAsync overload,

 var content = new JsonContent(myObject); // Update Content headers here var request = new HttpRequestMessage {RequestUri = uri, Content = content }; // Update request headers here _httpClient.SendAsync(request); 

Derived content classes are easy to create for almost any type of medium or any data source. I created all the classes derived from HttpContent. e.g. FileContent, EmbeddedResourceContent, CSVContent, XmlContent, ImageContent, HalContent, CollectionJsonContent, HomeContent, ProblemContent.

Personally, I have found that this gives me much better control over my payloads.

+4
source

I like that Darrell answers more than accepted, but he was still too complicated for me. I used this:

 public class ContentTypeSpecificStringContent : StringContent { /// <summary> /// Ensure content type is reset after base class mucks it up. /// </summary> /// <param name="content">Content to send</param> /// <param name="encoding">Encoding to use</param> /// <param name="contentType">Content type to use</param> public ContentTypeSpecificStringContent(string content, Encoding encoding, string contentType) : base(content, encoding, contentType) { Headers.ContentType = new MediaTypeHeaderValue(contentType); } } 

Needless to say, you can adapt it to what base class suits your needs. Hope that helps someone.

-one
source

All Articles