Json.NET:将嵌套数组反序列化为强类型对象

Posted

技术标签:

【中文标题】Json.NET:将嵌套数组反序列化为强类型对象【英文标题】:Json.NET: deserialize nested arrays into strongly typed object 【发布时间】:2012-10-15 14:13:22 【问题描述】:

我正在编写客户端应用程序,它应该处理服务器响应。响应采用 JSON 格式。我决定使用 Json.NET 来反序列化它们。而且我无法简化或修改这些响应(在服务器端)。这个特定 JSON 响应的特别困难是不同的对象类型在同一个数组中:哈希和文件数组。所以,我想直接将这个数组反序列化为强类型对象,而不是对象数组。我认为使用CustomCreationConverter 应该可以实现,但我不知道如何实现。

JSON:


    "files":
    [
        "hash string",
        [
            ["first file name", 12],
            ["second file name", 34]
        ]
    ]

我正在尝试实现的对象结构:

public class RootObject

    [JsonProperty("files")]
    public FilesContainer Container
    
        get;
        set;
    


public class FilesContainer

    public string Hash
    
        get;
        set;
    

    public File[] Files
    
        get;
        set;
    


[JsonConverter(typeof(FileJsonConverter))]
public class File

    public string Name
    
        get;
        set;
    

    public int Size
    
        get;
        set;
    


class FileJsonConverter : JsonConverter

    public override bool CanConvert(Type objectType)
    
        throw new NotImplementedException();
    

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    
        File obj = new File
        
            Name = reader.ReadAsString(),
            Size = reader.ReadAsInt32().GetValueOrDefault()
        ;

        reader.Read();

        return obj;
    

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

【问题讨论】:

【参考方案1】:

我终于想出了如何做到这一点。我需要在JsonConverter 中使用serializer.Deserialize。所以,这是一个工作示例。

class Program

    static string json = @"
                                ""files"":
                                [
                                    ""hash string"",
                                    [
                                        [""first file name"", 12],
                                        [""second file name"", 34]
                                    ]
                                ]
                            ";

    static void Main(string[] args)
    
        RootObject container = JsonConvert.DeserializeObject<RootObject>(json);
    


public class RootObject

    [JsonProperty("files")]
    public FilesContainer Container
    
        get;
        set;
    


[JsonConverter(typeof(FilesContainerJsonConverter))]
public class FilesContainer

    public string Hash
    
        get;
        set;
    

    public File[] Files
    
        get;
        set;
    


public class FilesContainerJsonConverter : JsonConverter

    public override bool CanConvert(Type objectType)
    
        throw new NotImplementedException();
    

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    
        FilesContainer obj = new FilesContainer();
        obj.Hash = reader.ReadAsString();
        reader.Read(); // to StartArray
        obj.Files = serializer.Deserialize<File[]>(reader);
        reader.Read(); // to EndArray

        return obj;
    

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


[JsonConverter(typeof(FileJsonConverter))]
public class File

    public string Name
    
        get;
        set;
    

    public int Size
    
        get;
        set;
    


class FileJsonConverter : JsonConverter

    public override bool CanConvert(Type objectType)
    
        throw new NotImplementedException();
    

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    
        File obj = new File
        
            Name = reader.ReadAsString(),
            Size = reader.ReadAsInt32().GetValueOrDefault()
        ;

        reader.Read(); // to EndArray

        return obj;
    

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

【讨论】:

以上是关于Json.NET:将嵌套数组反序列化为强类型对象的主要内容,如果未能解决你的问题,请参考以下文章

无法将 JSON 数组反序列化为类型 - Json.NET

将JSON数组反序列化为强类型的.NET对象

如何将具有固定模式的值数组反序列化为强类型数据类?

无法将当前 JSON 数组(例如 [1,2,3])反序列化为具有复杂和嵌套对象的类型

使用 Json.NET 将异构 JSON 数组反序列化为协变 List<>

使用 Json.net 将 JSON 对象反序列化为动态对象