如何为System.Text.Json.JsonSerializer全局设置默认选项?

时间:2019-10-10 21:42:41

标签: c# json serialization .net-core system.text.json

更新[2019-12-23]: 部分原因是由于语音community input对于.NET 5.0的问题added to the roadmap

更新[2019-10-10]: 如果有兴趣看到针对 System.Text.Json.JsonSerializer < em> 转到the open GitHub issue指出的 Chris Yungmann 并称重。


代替此:

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

我想做这样的事情:

// 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); 

希望在我们最常见的情况下不必传递JsonSerializerOptions的实例,而对异常(而不是规则)进行覆盖。

this q & a中所述,这是Json.Net的有用功能。我在the documentation中寻找System.Text.Json,在this GitHub repo中寻找Core。还有this one

在Core-3中似乎没有类似的方法可以管理JSON序列化默认设置。还是我忽略了它?

6 个答案:

答案 0 :(得分:5)

这似乎对我有用,在 StartUp.ConfigureServices 中:

services.AddControllers().AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
        options.JsonSerializerOptions.PropertyNamingPolicy=JsonNamingPolicy.CamelCase;
    });

答案 1 :(得分:3)

否,JsonSerializerOptions不公开default options。如果您使用的是特定的Web框架,则可以通过该方法指定(反序列化)设置。否则,建议您创建自己的便捷方法。

另请参阅this open issue

答案 2 :(得分:1)

您可以创建扩展方法。 Here's an example

我使用单独的方法,而不必构建特殊的设置,因此所有设置将集中在一个位置,并且易于重用。

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);
    }
}

然后将其作为字符串(无论是文字还是变量)上的方法来调用。

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

答案 3 :(得分:0)

GitHub用户workaround已提出一个andre-ss6,如下所示:

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

答案 4 :(得分:0)

.NET Core 3.1的interpretation中未公开默认选项。但是,截至2019年12月,该价格为added to the road map,为5.0。

.NET 5.0的发布日期为expected,即2020年11月。但是不能保证在任何特定时间都会解决此特定问题。除了等待之外,这些答案还提供了解决方法:

答案 5 :(得分:-1)

(如果您切换到使用Json.NET)

我更喜欢并建议您将其设置为显式并将设置传递给所有呼叫,但是您可以使用DefaultSettings设置默认值。

JsonConvert.DefaultSettings = () => MySuperJsonSerializerSettings;

然后

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