How to send JSON in C# with DataContractJsonSerializer without charset?
Asked Answered
K

3

7

I use DataContractJsonSerializer and StringContent to send JSON to a web service:

DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Employee));
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, employee);
ms.Position = 0;
StreamReader sr = new StreamReader(ms);
StringContent jsonContent = new StringContent(sr.ReadToEnd(),
                               System.Text.Encoding.UTF8, "application/json");
// later I do HttpClient.PostAsync(uri, jsonContent)

This results in this Content-Type header:

Content-Type: application/json; charset=utf-8

Is it possible to leave off the charset and just have the following header?

Content-Type: application/json

I don't see an overload on StringContent which does this.

Kell answered 19/4, 2013 at 6:29 Comment(6)
If you do not specify encoding, which one server side should use: ASCII, UTF-8, UTF-16?Buchholz
@Garath: if you don't specify the encoding or the media type, StringBuilder defaults to text/plain. I need application/json. msdn.microsoft.com/en-us/library/hh158908.aspxKell
I know this. But you want to remove charset from reqest. Charset is same to encoding. If your request will be "Content-Type: application/json" how server should interpret it?Buchholz
I misunderstood you. I believe the server assumes the request is UTF-8, because that's what it sends back.Kell
So why you want to delete this information from request? If you set it is much more clearBuchholz
The API I'm talking to does not work when the charset is specified. It only works when the charset is not there.Kell
S
12

When a new instance of the StringContent class is initialized via

public StringContent(
    string content,
    Encoding encoding,
    string mediaType
)

following HTTP request header for Content Type is generated:

Content-Type: application/json; charset=utf-8

Pay attention to the presence of encoding part ( charset=utf-8)

In order to construct Content Type header without encoding part, the following options could be considered:

1) Using StringContent Constructor (String) and setting content type using ContentType property, for example:

var requestContent = new StringContent(jsonContent);                
requestContent.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json");

or

var requestContent = new StringContent(jsonContent);                
requestContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

2) Remove encoding part from ContentType property, for example:

    var requestContent = new StringContent(jsonContent, System.Text.Encoding.UTF8, "application/json");
    requestContent.Headers.ContentType.CharSet = null; 

3) Create custom JsonMediaTypeFormatter Class that resets encoding part:

public class NoCharsetJsonMediaTypeFormatter : JsonMediaTypeFormatter
{
    public override void SetDefaultContentHeaders(Type type, System.Net.Http.Headers.HttpContentHeaders headers, System.Net.Http.Headers.MediaTypeHeaderValue mediaType)
    {
        base.SetDefaultContentHeaders(type, headers, mediaType);
        headers.ContentType.CharSet = null;
    }
}
Spoliation answered 24/5, 2015 at 19:14 Comment(0)
B
8

I had been having the exact same problem, no matter what I set the charset to, it would always claim I was trying to use an "Unsupported Media Type". I found that using this method of leaving the charset blank (as Slack was trying to do) solved my problem. The trick is to specify the content type - which was absolutely required - later (I just did it on the next line):

StringContent content = new StringContent("Whatever=something");
content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json");

(Please excuse the not-really-JSON formatting of the content, that isn't the point of my example.)

Balthazar answered 4/3, 2014 at 1:17 Comment(0)
B
0

You can also use the JsonContent with a MediaType parameter:

var jsonContent = JsonContent.Create(new
            {
                something = "else"
            }, 
mediaType: new MediaTypeHeaderValue("application/json") {CharSet = null });
Blabber answered 26/4 at 6:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.