Newtonsoft JsonConvert.DefaultSettings奇怪的行为

时间:2018-11-09 09:49:55

标签: c# json.net

我遇到了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;

问题:是错误还是我不理解? 如果不是bug,有人可以向我解释这种行为吗?

突然之间,由于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}

    }
}

1 个答案:

答案 0 :(得分:0)

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

相关代码:

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

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