49

I'm trying to set the global serializer settings like this in my global.asax.

var formatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
formatter.SerializerSettings = new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    TypeNameHandling = TypeNameHandling.Objects,
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};

When serializing object using the following code the global serializer settings are not used?

return new HttpResponseMessage(HttpStatusCode.OK)
{
    Content = new StringContent(JsonConvert.SerializeObject(page))
};

Isn't it possible to set the global serializer settings like this or am I missing something?

marcus
  • 9,616
  • 9
  • 58
  • 108

4 Answers4

96

Setting the JsonConvert.DefaultSettings did the trick.

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    TypeNameHandling = TypeNameHandling.Objects,
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};
marcus
  • 9,616
  • 9
  • 58
  • 108
  • 5
    i had to set ``GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings`` to the same object to ensure that this config would be used everywhere. (in this case: by webapi and manually invoking via JsonConvert) – Simon Zyx Jan 13 '17 at 10:24
  • 9
    This does not work at all. The settings are completely ignored. – jwize Aug 29 '17 at 20:11
  • Works perfectly. In my case it was an external library used from a ASP.NET Core project. I added the following code to Startup (ConfigureServices) – Amr Ellafy Feb 19 '21 at 16:53
  • By the way, maybe it's better to store singleton instead of running "new JsonSerializerSettings" every time? What do you think? – Pavel Biryukov Jun 04 '21 at 12:32
9

Accepted answer did not work for me. In .netcore, I got it working with...

services.AddMvc(c =>
                 {
                 ....
                 }).AddJsonOptions(options => {
                     options.SerializerSettings.Formatting = Formatting.Indented;
                     ....
                 })
Michael
  • 1,177
  • 15
  • 15
  • 2
    If you are doing any manual serialization/deserialization using JsonConvert, you will need to use the accepted answer above. So you will need to set both if you want consistency. – Steven Pena May 10 '19 at 00:51
2

Just do the following in your action so that you can return a content-negotiated response and also your formatter settings can take effect.

return Request.CreateResponse(HttpStatusCode.OK, page);
Kiran
  • 56,921
  • 15
  • 176
  • 161
  • That worked like a charm, are there any pros or cons by using `Request.CreateResponse` rather then creating a `new HttpResponseMessage` like I did in my solution? – marcus Feb 16 '14 at 20:40
  • 3
    yes, you would loose content-negotiation...for example, if a request comes for `application/xml`, you would still be sending back json data ... – Kiran Feb 16 '14 at 20:46
1

You're correct about where to set the serializer. However, that serializer is used when the request to your site is made with a requested content type of JSON. It isn't part of the settings used when calling SerializeObject. You could work around this by exposing the JSON serialization settings defined global.asax via a property.

public static JsonSerializerSettings JsonSerializerSettings
{
    get
    {
        return GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
    }
}

And then use this property to set the serialization settings when doing serialization within your controllers:

return new HttpResponseMessage(HttpStatusCode.OK)
{
    Content = new StringContent(JsonConvert.SerializeObject(page, WebApiApplication.JsonSerializerSettings))
};
Scott Corbett
  • 380
  • 1
  • 7