首页 > 解决方案 > Newtonsoft JsonConvert.DefaultSettings 奇怪的行为

问题描述

我在我的应用程序中遇到了奇怪的行为(至少对我来说),JsonConvert.DefaultSettings
我为整个应用程序定义了默认的 json 设置,但是如果我需要某个对象的独占序列化,我认为我可以JsonSerializerSettings作为第二个参数传递给JsonConvert.SerializeObject该设置将覆盖默认值。但这似乎是不正确的。

我发现作为第二个参数传递的设置被忽略了。所以,如果我需要独占序列化并且有定义的默认设置,我必须这样做:

var defs = JsonConvert.DefaultSettings;
JsonConvert.DefaultSettings = null;
var settings = new JsonSerializerSettings();
var jsonString = JsonConvert.SerializeObject(someObject, settings);
JsonConvert.DefaultSettings = defs;

问题:这是一个错误还是我只是不明白什么?如果它不是错误,有人可以向我解释这种行为吗?

由于https://dotnetfiddle.net上的 nuget 包损坏,我现在无法准备小提琴

但这里是这种情况的一个例子:

using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;

public class Program
{
    public enum TestEnum {
        Zero,
        One,
        Two
    }

    public class Something
    {
        public string Name {get; set;}
        public TestEnum Num {get; set;}
    }

    public void Main()
    {
        var test = new Something {
            Name = "foo",
            Num = TestEnum.One
        };

        string json = JsonConvert.SerializeObject(test);
        Console.WriteLine(json);
        // {"Name":"foo","Num":1}

        JsonConvert.DefaultSettings = (() =>
            {
            var JsonSetting = new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver(),
            };
            JsonSetting.Converters.Add(new StringEnumConverter()
            {
                CamelCaseText = true
            });

            return JsonSetting;
        });     


        json = JsonConvert.SerializeObject(test);
        Console.WriteLine(json);
        //{"name":"foo","num":"one"}


        var settings = new JsonSerializerSettings();
        json = JsonConvert.SerializeObject(test, settings);
        Console.WriteLine(json);
        //this will result in: {"name":"foo","num":"one"}
        //but i expect this:  {"Name":"foo","Num":1}

    }
}

标签: c#json.net

解决方案


如果实例化一个新JsonSerializerSettings实例,它的ContractResolver属性是null. 然后在 中JsonConvert.SerializeObject()JsonSerializer实例化 a 并使用传递的设置进行配置。

相关代码:

if (settings.ContractResolver != null)
    serializer.ContractResolver = settings.ContractResolver;

JsonSerializer构造函数将其初始化ContractResolverDefaultContractResolver.Instance。因此,如果您未在传递的设置中指定合同解析器,它将解析为默认值。


推荐阅读