Keep casing when serializing dictionaries

后端 未结 4 1981
故里飘歌
故里飘歌 2020-11-28 08:07

I have a Web Api project being configured like this:

config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContract         


        
4条回答
  •  渐次进展
    2020-11-28 09:11

    There is not an attribute to do this, but you can do it by customizing the resolver.

    I see that you are already using a CamelCasePropertyNamesContractResolver. If you derive a new resolver class from that and override the CreateDictionaryContract() method, you can provide a substitute DictionaryKeyResolver function that does not change the key names.

    Here is the code you would need:

    class CamelCaseExceptDictionaryKeysResolver : CamelCasePropertyNamesContractResolver
    {
        protected override JsonDictionaryContract CreateDictionaryContract(Type objectType)
        {
            JsonDictionaryContract contract = base.CreateDictionaryContract(objectType);
    
            contract.DictionaryKeyResolver = propertyName => propertyName;
    
            return contract;
        }
    }
    

    Demo:

    class Program
    {
        static void Main(string[] args)
        {
            Foo foo = new Foo
            {
                AnIntegerProperty = 42,
                HTMLString = "",
                Dictionary = new Dictionary
                {
                    { "WHIZbang", "1" },
                    { "FOO", "2" },
                    { "Bar", "3" },
                }
            };
    
            JsonSerializerSettings settings = new JsonSerializerSettings
            {
                ContractResolver = new CamelCaseExceptDictionaryKeysResolver(),
                Formatting = Formatting.Indented
            };
    
            string json = JsonConvert.SerializeObject(foo, settings);
            Console.WriteLine(json);
        }
    }
    
    class Foo
    {
        public int AnIntegerProperty { get; set; }
        public string HTMLString { get; set; }
        public Dictionary Dictionary { get; set; }
    }
    

    Here is the output from the above. Notice that all of the class property names are camel-cased, but the dictionary keys have retained their original casing.

    {
      "anIntegerProperty": 42,
      "htmlString": "",
      "dictionary": {
        "WHIZbang": "1",
        "FOO": "2",
        "Bar": "3"
      }
    }
    

提交回复
热议问题