How can I serialize/deserialize a dictionary with custom keys using Json.Net?

后端 未结 3 734
误落风尘
误落风尘 2020-11-28 13:15

I have the following class, that I use as a key in a dictionary:

    public class MyClass
    {
        private readonly string _property;

        public My         


        
3条回答
  •  Happy的楠姐
    2020-11-28 13:43

    Grx70's answer is good - just adding an alternative solution here. I ran into this problem in a Web API project where I wasn't calling SerializeObject but allowing the serialization to happen automagically.

    This custom JsonConverter based on Brian Rogers' answer to a similar question did the trick for me:

    public class DeepDictionaryConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return (typeof(IDictionary).IsAssignableFrom(objectType) ||
                    TypeImplementsGenericInterface(objectType, typeof(IDictionary<,>)));
        }
    
        private static bool TypeImplementsGenericInterface(Type concreteType, Type interfaceType)
        {
            return concreteType.GetInterfaces()
                   .Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == interfaceType);
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            Type type = value.GetType();
            IEnumerable keys = (IEnumerable)type.GetProperty("Keys").GetValue(value, null);
            IEnumerable values = (IEnumerable)type.GetProperty("Values").GetValue(value, null);
            IEnumerator valueEnumerator = values.GetEnumerator();
    
            writer.WriteStartArray();
            foreach (object key in keys)
            {
                valueEnumerator.MoveNext();
    
                writer.WriteStartArray();
                serializer.Serialize(writer, key);
                serializer.Serialize(writer, valueEnumerator.Current);
                writer.WriteEndArray();
            }
            writer.WriteEndArray();
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    

    In my case, I was serializing a Dictionary property on a class where MyCustomType had properties like Name and Id. This is the result:

    ...
    "dictionaryProp": [
        [
          {
            "name": "MyCustomTypeInstance1.Name",
            "description": null,
            "id": null
          },
          3
        ],
        [
          {
            "name": "MyCustomTypeInstance2.Name",
            "description": null,
            "id": null
          },
          2
        ]
    ]
    ...
    

提交回复
热议问题