How to globally set default options for System.Text.Json.JsonSerializer?

守給你的承諾、 提交于 2019-12-10 06:53:05

问题


UPDATE: If interested in seeing this behavior implemented for System.Text.Json.JsonSerializer head on over to the open GitHub issue pointed out by Chris Yungmann and weigh in.


Instead of this:

JsonSerializerOptions options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
    // etc.
};
JsonSerializer.Deserialize<SomeObject>(someJsonString, options);

I would like to do something like this:

// This property is a pleasant fiction
JsonSerializer.DefaultSettings = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
    // etc.
};

// This uses my options
JsonSerializer.Deserialize<SomeObject>(someJsonString); 

// And somewhere else in the same codebase...
// This also uses my options
JsonSerializer.Deserialize<SomeOtherObject>(someOtherJsonString); 

The hope is to not have to pass an instance of JsonSerializerOptions for our most common cases, and override for the exception, not the rule.

As indicated in this q & a, this is a useful feature of Json.Net. I looked in the documentation for System.Text.Json as well as this GitHub repo for Core. And this one.

There doesn't seem to be an analog for managing JSON serialization defaults in Core-3. Or am I overlooking it?


回答1:


No, JsonSerializerOptions does not expose the default options. If you are using a particular web framework there may be a way to specify (de-)serialization settings through that. Otherwise, I suggest creating your own convenience methods.

See also this open issue.




回答2:


You can create an extension method. Here's an example

I use separate methods vs having to build special settings, so that all the settings will be in a single spot and easily reusable.

public static class DeserializeExtensions
{
    private static JsonSerializerOptions defaultSerializerSettings = new JsonSerializerOptions();

    // set this up how you need to!
    private static JsonSerializerOptions featureXSerializerSettings = new JsonSerializerOptions();


    public static T Deserialize<T>(this string json)
    {       
        return JsonSerializer.Deserialize<T>(json, defaultSerializerSettings);
    }

    public static T DeserializeCustom<T>(this string json, JsonSerializerOptions settings)
    {
        return JsonSerializer.Deserialize<T>(json, settings);
    }

    public static T DeserializeFeatureX<T>(this string json)
    {
        return JsonSerializer.Deserialize<T>(json, featureXSerializerSettings);
    }
}

Then you call it as a method on a string, whether literal or a variable.

    Car result = @"{""Wheels"": 4, ""Doors"": 2}".DeserializeFeatureX<Car>();



回答3:


(If you ever switch to using Json.NET)

I prefer and recommend being explicit and pass settings to all calls, but you can set defaults with DefaultSettings.

JsonConvert.DefaultSettings = () => MySuperJsonSerializerSettings;

and then

var json = JsonConvert.SerializeObject(o1);
var o2 = JsonConvert.DeserializeObject(x);



回答4:


A workaround has been proposed by GitHub user andre-ss6 as follows:

((JsonSerializerOptions)typeof(JsonSerializerOptions)
    .GetField("s_defaultOptions", 
        System.Reflection.BindingFlags.Static |
        System.Reflection.BindingFlags.NonPublic).GetValue(null))
    .PropertyNameCaseInsensitive = true;


来源:https://stackoverflow.com/questions/58331479/how-to-globally-set-default-options-for-system-text-json-jsonserializer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!