Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keep casing when serializing dictionaries

Tags:

c#

json.net

I have a Web Api project being configured like this:

config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

However, I want dictionary keys casing to remain unchanged. is there any attribute in Newtonsoft.Json I can use to a class to denote that I want casing to remain unchanged during serialization?

public class SomeViewModel {     public Dictionary<string, string> Data { get; set; }     } 
like image 726
zafeiris.m Avatar asked Jun 10 '14 14:06

zafeiris.m


People also ask

Can I serialize a dictionary?

Serializing Dictionaries With UnityBy making a new class that inherits both Dictionary and Unity's ISerializationCallbackReceiver interface, we can convert the Dictionary data to a format that Unity can serialize. And, with that, we have Dictionaries that can be used in Unity.

Can JSON serialize dictionary?

Json can't serialize Dictionary unless it has a string key. The built-in JSON serializer in . NET Core can't handle serializing a dictionary unless it has a string key.

Can you serialize a dictionary C#?

NET objects is made easy by using the various serializer classes that it provides. But serialization of a Dictionary object is not that easy. For this, you have to create a special Dictionary class which is able to serialize itself. The serialization technique might be different in different business cases.

What is CamelCasePropertyNamesContractResolver?

CamelCasePropertyNamesContractResolver. CamelCasePropertyNamesContractResolver inherits from DefaultContractResolver and simply overrides the JSON property name to be written in camelcase. ContractResolver.


1 Answers

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 = "<html></html>",             Dictionary = new Dictionary<string, string>             {                 { "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<string, string> 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": "<html></html>",   "dictionary": {     "WHIZbang": "1",     "FOO": "2",     "Bar": "3"   } } 
like image 159
Brian Rogers Avatar answered Sep 18 '22 18:09

Brian Rogers