简体   繁体   English

Newtonsoft JsonConvert.DefaultSettings奇怪的行为

[英]Newtonsoft JsonConvert.DefaultSettings strange behavior

I've faced with strange behavior(at least for me) of JsonConvert.DefaultSettings 我遇到了JsonConvert.DefaultSettings奇怪行为(至少对我来说)
In my apps i define default json settings for whole app, but in case if i need exclusive serialization of some object i thought that i can pass JsonSerializerSettings as second argument to JsonConvert.SerializeObject and that settings will override the default one. 在我的应用程序中,我为整个应用程序定义了默认的json设置,但是如果我需要某些对象的排他序列化,我认为我可以将JsonSerializerSettings作为第二个参数传递给JsonConvert.SerializeObject并且该设置将覆盖默认值。 but it seems that this is not correct. 但这似乎是不正确的。

I found that settings passed as second argument are ignored. 我发现作为第二个参数传递的设置将被忽略。 so, if i need exclusive serialization and there is defined default settings i have to do something like that: 因此,如果我需要排他性序列化并且定义了默认设置,则必须执行以下操作:

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

Question : Is it a bug or i just do not understand something? 问题 :这是一个错误还是我不明白? if its not a bug, can someone explain me this behavior? 如果不是bug,有人可以向我解释这种行为吗?

Suddenly i can not prepare fiddle at the moment because of broken nuget packages at https://dotnetfiddle.net 突然我无法准备小提琴,因为https://dotnetfiddle.net上的 nuget包损坏了

but here is an example of this case: 但是这里是这种情况的一个例子:

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}

    }
}

If you instantiate a new JsonSerializerSettings instance, its ContractResolver property is null . 如果实例化新的JsonSerializerSettings实例,则其ContractResolver属性为null Then in JsonConvert.SerializeObject() , a JsonSerializer is instantiated and configured with the passed settings. 然后在JsonConvert.SerializeObject() ,实例化JsonSerializer并使用传递的设置对其进行配置。

Relevant code: 相关代码:

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

The JsonSerializer 's constructor initializes its ContractResolver to DefaultContractResolver.Instance . JsonSerializer的构造函数将其ContractResolver初始化为DefaultContractResolver.Instance So if you don't specify a contract resolver in the settings you pass, it'll resolve to the default. 因此,如果您在传递的设置中未指定合同解析器,它将解析为默认值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM