Search code examples
c#serializationjson.net

Force lowercase JSON serialization of dictionary keys while using camel case for class properties


I have the following property:

    [JsonProperty()]
    public Dictionary<string, ICollection<string>> Foo { get; set; }

How can I use the [JsonProperty] attribute to force the dictionary key to serialize in all lowercase?

For example, I'd like these keys to serialize the following way:

  1. ABC1 -> abc1
  2. DEF2 -> def2

My global configuration (Web API) uses the CamelCasePropertyNamesContractResolver, which results in the following serialization of above keys:

  1. ABC1 -> abC1
  2. DEF2 -> deF2

Solution

  • You can solve this by implementing a custom NamingStrategy deriving from the CamelCaseNamingStrategy. It's just a few lines of code:

    public class CustomNamingStrategy : CamelCaseNamingStrategy
    {
        public CustomNamingStrategy()
        {
            ProcessDictionaryKeys = true;
            ProcessExtensionDataNames = true;
            OverrideSpecifiedNames = true;
        }
    
        public override string GetDictionaryKey(string key)
        {
            return key.ToLower();
        }
    }
    

    Then replace the CamelCasePropertyNamesContractResolver in your Web API global configuration with a DefaultContractResolver which uses the new naming strategy:

    GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver = 
        new DefaultContractResolver() { NamingStrategy = new CustomNamingStrategy };
    

    Here is a working demo (console app): https://dotnetfiddle.net/RVRiJY

    Note: naming strategies are supported via [JsonProperty] and [JsonObject] attributes in Json.Net, but sadly the dictionary keys don't appear to get processed when you apply the strategy that way. At least it did not seem to work in my testing. Setting the strategy via resolver seems to be the way to go for what you are trying to accomplish.