在自定义JsonConverter中反序列化嵌套对象List

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在自定义JsonConverter中反序列化嵌套对象List相关的知识,希望对你有一定的参考价值。

我已经制作了一个自定义的JSON转换器来处理我收到的JSON,但是我在解析嵌套对象列表时遇到了一些麻烦。我的JSON目前看起来像这样:

JSON:

{ 
"messageID": "1", 
"item": 
    { "type": "text", 
    "textlist": [ { "text": "just some text" }]
    }
}

在我的例子中,我创建了一些可以转换为的类。我有一个Message类,它将转换器应用于项目。 item属性是一个接口,它具有TextItem类形式的实现。

public class Message
    {
    [JsonProperty("messageID")]
    public string messageID { get; set; }

    [JsonConverter(typeof(ItemConverter))]
    public IItem item { get; set; }

    public Message(string msgID, IItem itm)
    {
        messageID = msgID;
        item = itm;
    }
}

public class TextItem : IItem
{
    [JsonProperty("type")]
    public string type { get; set; }
    [JsonProperty("textlist")]
    public List<Text> textlist { get; set; }

    string IItem.Type
    {
        get => type;
        set => type = value;
    }

    public TextItem(List<Text> txtlst)
    {
        type = "text";
        textlist = txtlst;
    }
}

public class Text
{
    [JsonProperty("text")]
    public string text { get; set; }

    public Text(string txt)
    {
        text = txt;
    }
}

有很多不同类型的项目,这就是我有ItemConverter的原因:

public class ItemConverter : JsonConverter
    {
        public override object ReadJson(JsonReader reader,
        Type objectType, object existingValue,
        JsonSerializer serializer)
    {
        var jsonObject = JObject.Load(reader);
        var item= default(IItem);
        switch (jsonObject["type"].Value<string>())
        {
            case "text":
                item= new TextItem(jsonObject["textlist"].Value<List<Text>>());
                break;
    // omitted non relevant cases
        }

        serializer.Populate(jsonObject.CreateReader(), item);
        return item;
    }
}

但是,调用DeserializeObject只会导致错误

JsonConvert.DeserializeObject<Message>(userMessage) 

// I get the following error:
System.ArgumentNullException: Value cannot be null.

所有其他情况(没有列表)处理得很好。有关为什么嵌套列表没有正确转换的任何想法?

答案

你的课程搞砸了,

使用public string type { get; set; }来获取您需要的物品

你的课可能看起来像这样

public class Textlist
{
    public string text { get; set; }
}

public class Item
{
    public string type { get; set; }
    public List<Textlist> textlist { get; set; }
}

public class RootObject
{
    public string messageID { get; set; }
    public Item item { get; set; }
}

现在你可以在RootObject上反序列化了

以上是关于在自定义JsonConverter中反序列化嵌套对象List的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Spring Boot 中反序列化嵌套对象“Role”

Django Rest Framework:如何将数据传递给嵌套的序列化器并仅在自定义验证后创建对象

在json中反序列化嵌套列表的最佳方法 - C#

如何使用 Gson @SerializedName 注释在 Kotlin 中反序列化嵌套的 Json API 响应

NewtonSoft JsonConverter - 访问其他属性

c# 通过json.net中的JsonConverter进行自定义序列化与反序列化