6

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.

dbc
  • 104,963
  • 20
  • 228
  • 340
royco
  • 5,409
  • 13
  • 60
  • 84
  • If you do not specify encoding, which one server side should use: ASCII, UTF-8, UTF-16? – Piotr Stapp Apr 19 '13 at 06:40
  • @Garath: if you don't specify the encoding or the media type, StringBuilder defaults to text/plain. I need application/json. http://msdn.microsoft.com/en-us/library/hh158908.aspx – royco Apr 19 '13 at 06:44
  • 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? – Piotr Stapp Apr 19 '13 at 06:47
  • I misunderstood you. I believe the server assumes the request is UTF-8, because that's what it sends back. – royco Apr 19 '13 at 15:40
  • So why you want to delete this information from request? If you set it is much more clear – Piotr Stapp Apr 19 '13 at 17:03
  • 2
    The API I'm talking to does not work when the charset is specified. It only works when the charset is not there. – royco Apr 20 '13 at 06:34

2 Answers2

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;
    }
}
Vadim Gremyachev
  • 57,952
  • 20
  • 129
  • 193
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.)

user1789459
  • 101
  • 1
  • 4