1

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
Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
tmaurst
  • 552
  • 3
  • 14
  • 34
  • 1
    Possible duplicate of [Ensuring json keys are lowercase in .NET](https://stackoverflow.com/questions/6288660/ensuring-json-keys-are-lowercase-in-net) – Dave Sep 12 '19 at 18:28
  • You can do so by writing a custom class of `DefaultContractResolver` just override `ResolveDictionaryKey` method to retrieve lowercase string. – muaz Sep 12 '19 at 18:34
  • @muaz - Got it. How would I then feed that new ContractResolver to the JsonProperty() attribute? – tmaurst Sep 12 '19 at 18:42
  • @tmaurst You cannot use the attribute for this. You need to have a custom resolver. – David Pilkington Sep 12 '19 at 18:48
  • Alternative solution to what was mentioned already would be to replace your `Dictionary` with another class, and in that class define the keys with `JsonProperty` attribute names that are lowercase. This would only work if the keys in your `Dictionary` are always static (and known ahead of time) – Omar Himada Sep 12 '19 at 18:57

2 Answers2

0

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.

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
  • This code just making the property names lower case not camel case! key.ToLower(); – Mohammad Nikravesh Feb 24 '20 at 13:25
  • 2
    @MohammadNikravesh The OP asked that dictionary keys be all lower case, while everything else be camel case. So that is what this code does. See the example at https://dotnetfiddle.net/RVRiJY – Brian Rogers Feb 24 '20 at 16:40
0

You can try this:

 builder.Services.AddJsonOptions(opts =>
    {
        opts.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;

        // this line
        opts.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
    });