Search code examples
c#jsonasp.net-mvc-4jsonserializer

Serialize IEnumerable<IDictionary<string, object>> doesn't work with DefaultNamingStrategy


By default I use CamelCasePropertyNamesContractResolver in my project for serialize to json. But I want to change this strategy for one property.

public class ViewTable
{
    public int Id { get; set; }

    [JsonProperty(NamingStrategyType = typeof(DefaultNamingStrategy), ItemTypeNameHandling = TypeNameHandling.None, TypeNameHandling = TypeNameHandling.None)]
    public IEnumerable<IDictionary<string, object>> Rows { get; set; }
}

So when I serialize this object I expect to get such json:

"result": {
    "id": 15,
    "rows": [
      {
        "SessionData_Department": "",
        "SystemData_SerialNumber": "1"
      }
    ]
}

But I got:

"result": {
    "id": 15,
    "Rows": [   //There must be a lowercase!!!
      {
        "sessionData_Department": "", //There must be a uppercase!!!
        "systemData_SerialNumber": "1"
      }
    ]
}

I have such json settings in my project:

    var settings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
    settings.Formatting = Formatting.Indented;
    settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    settings.TypeNameHandling = TypeNameHandling.Auto;

How can I tell json serializer use DefaultNamingStrategy for IDictionary?


Solution

  • I'm not sure that there is a setting from out-of-the box. But you can do it by extending JsonConverter and using DefaultContractResolver:

    public class RowsConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            throw new NotImplementedException();
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var settings = new JsonSerializerSettings()
            {
                ContractResolver = new DefaultContractResolver()
            };
            writer.WriteRawValue(JsonConvert.SerializeObject(value, settings));
        }
    }
    

    Then change Rows property to:

    [JsonProperty(ItemConverterType = typeof(RowsConverter))]
    public IEnumerable<IDictionary<string, object>> Rows { get; set; }