字典或对象列表的条件反序列化

时间:2018-11-23 13:12:16

标签: c# json json.net deserialization

我正在向REST API发送GET请求,该请求以两种不同的格式返回JSON(基于我无法影响的某些外部设置)。 我可以收到:

"content": {
    "fields": [
     {
         "name": "test1",
         "value": 1
     },
     {
         "name": "test2",
         "value": "test"
     },
     {
         "name": "test3",
         "value": "test",
         "links": [...]
     }
   ]
}

"content": {
  "test1": 1,
  "test2": "test",
  "test3": "test"
}

您会看到我收到的对象列表包含namevalue属性(以及其他一些属性,例如links),或者我收到的对象包含单个键-值字典中的值对。我现在想知道是否有一种方法可以将JSON具有Dictionary<string, string>List<Field>属性的条件反序列化为一个类,如下所示:

[Serializable]
public class Content
{
    /// <summary>
    /// The Type of the Content
    /// </summary>
    public string _Type { get; set; }

    public Dictionary<string, string> Dictionary { get; set; }

    public List<Field> Fields { get; set; }
}

并根据JSON填充字典或字段列表。

1 个答案:

答案 0 :(得分:1)

您可以通过为Content类创建自定义JsonConverter来解决这种情况,如下所示。通过将JSON的content部分加载到JObject中并检查fields属性的存在来确定如何填充Content实例,来工作。

public class ContentConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Content);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        Content content = new Content();
        if (jo["fields"] != null)
        {
            // if the fields property is present, we have a list of fields
            content.Fields = jo["fields"].ToObject<List<Field>>(serializer);
            content._Type = "Fields";
        }
        else
        {
            // fields property is not present so we have a simple dictionary
            content.Dictionary = jo.Properties().ToDictionary(p => p.Name, p => (string)p.Value);
            content._Type = "Dictionary";
        }
        return content;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

我不确定您要如何处理_Type属性,因此我只是将其设置为“ Fields”或“ Dictionary”以指示填充了哪个属性。随时更改它以适合您的需求。

要使用转换器,只需将[JsonConverter]属性添加到Content类中,如下所示:

[JsonConverter(typeof(ContentConverter))]
public class Content
{
    ...
}

这是一个有效的演示:https://dotnetfiddle.net/geg5fA