Search code examples
c#asp.net-corejson.net

Deserialize Nested Dictionary in from Json C#


I have a class something like this

public class A{
    public Guid userId { get; set; }
    public Guid businessId { get; set; }
    public Dictionary<int, long> rights { get; set; }
}

And I want to covert this json to this class

    {
    "userId": "dc2af693-72e1-49a7-80aa-6416c6536bdf",
    "businessId": "0110eea4-7a47-4a7c-95ea-10547ab49652",
    "rights": "{\"19\":1,\"17\":15,\"18\":1,\"23\":1,\"1\":31,\"20\":3,\"3\":1,\"16\":0}",
   }

But when Im trying to convert it with NewtonSoft.Json

JsonConvert.DeserializeObject<A>(json);

I get the following error Cannot Cast System.string to System.Dictionary<int,long> What happens is that my rights get converted to a string something like this

"{"19":1, "17":15, "18":1, ..., "16":0}"

If I deserialize this string again it works as I desire is there better method to do this.


Solution

  • Since the rights is in string format, you can add custom JsonConverter which converts the string to dictionary

    public class A
    {
        public Guid userId { get; set; }
        public Guid businessId { get; set; }
        [JsonConverter(typeof(RightsSerializer))]
        public Dictionary<int, long> rights { get; set; }
    }
    

    Here is the RightsSerializer

    public class RightsSerializer : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Dictionary<int, long>);
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null) return null;
    
            var jt = JToken.Load(reader);
            return JsonConvert.DeserializeObject<Dictionary<int, long>>(jt.Value<String>());
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            serializer.Serialize(writer, value);
        }
    }
    

    And DeserializeObject

    var json = File.ReadAllText("json1.json");
    var result = JsonConvert.DeserializeObject<A>(json);