简体   繁体   中英

C# Polymorphic JSON deserialization for Dictionary/List objects

I need to deserialize dynamic JSON text that can represent either System.Collections.Generic.Dictionary<string, T> or System.Collections.Generic.List< T>. I suppose I have to write custom converter but I'm not sure about how it should look like properly. I'm using .NET5's System.Text.Json.

Sample JSON for dictionary type (sent almost all the time):

{
"1":
    {
       "13346964555":
          {
              "data1":1,
              "data2":2
          },
        "13346964556":
          {
              "data1":1,
              "data2":2
          },
     }
}

Sample JSON for list type (rare, needs to be converted into dictionary with empty string keys):

{
"1": [
     {
        "data1":1,
        "data2":2
     },
     {
        "data1":1,
        "data2":2
     }
   ]
}

On the other side, converting from normal dictionary to list of its values is acceptable as well, since I don't need keys at all currently.

ended up with this converter, from Dictionary to List, based on another example. seems to work fine in my case. feel free to discuss if something is wrong here. note that I only need to convert specific dictionary type, so no need for converters' factory here.

public class DictionaryToListConverter : JsonConverter<List<type>>
{
    public override bool CanConvert(Type typeToConvert)
    {
        return typeof(List<type>) == typeToConvert;
    }

    public override List<type> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        bool is_array = reader.TokenType == JsonTokenType.StartArray;
        bool is_dictionary = reader.TokenType == JsonTokenType.StartObject;

        if (is_array || is_dictionary)
        {
            var list = new List<type>();

            while (reader.Read())
            {
                if ((is_array && reader.TokenType == JsonTokenType.EndArray) || (is_dictionary && reader.TokenType == JsonTokenType.EndObject))
                    return list;

                if (is_dictionary)
                {
                    if (reader.TokenType != JsonTokenType.PropertyName)
                        throw new JsonException();

                    reader.Read(); // skip the key and move to value.
                }

                list.Add(JsonSerializer.Deserialize<type>(ref reader));
            }
        }

        throw new JsonException();
    }

    public override void Write(Utf8JsonWriter writer, List<type> value, JsonSerializerOptions options)
    {
        // ...
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM