首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Json.net反序列化为可能包含数组或嵌套数组的JSon对象。

Json.net反序列化为可能包含数组或嵌套数组的JSon对象。
EN

Stack Overflow用户
提问于 2014-02-21 17:21:07
回答 4查看 1.6K关注 0票数 2

我有许多JSon文件,我正在使用这些文件进行反序列化

JsonSerializer serializer = new JsonSerializer(); t obj = (t)serializer.Deserialize(file, typeof(t));

对象的集合。除其他外,它们包含以下数据。“可信任”中的数组数由“门”的值决定。

代码语言:javascript
复制
"gates" : 1,
"truthtable" : [ false, true ]

代码语言:javascript
复制
"gates" : 2,
"truthtable" : [ [ false, false ], [ false, true ] ]

如果我试图将"truthtable“反序列化为以下属性,则示例1将失败。

代码语言:javascript
复制
public List<List<bool>>truthtable { get; set; }

有任何方法可以反序列化这两种不同类型的可信任对象到同一个对象吗?我已经尝试过构建一个自定义反序列化器,但是Json认为两者都是"JsonToken.StartArray",所以不能这样区分。

理想情况下,我希望能够反序列化这两个示例,就像它们是布尔数组一样。

编辑应该提到,我不能改变创建Json文件的方式。我无法接触到他们的创造。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-02-21 23:54:04

这个问题可以使用自定义JsonConverter来解决。转换器可以读取门数,然后相应地填充List<List<bool>>。如果只有一个门,它可以将单个列表封装在外部列表中,以使其与您的类一起工作。

假设您试图将类反序列化为如下所示:

代码语言:javascript
复制
class Chip
{
    public int Gates { get; set; }
    public List<List<bool>> TruthTable { get; set; }
}

然后转换器看起来可能如下所示:

代码语言:javascript
复制
class ChipConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Chip));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);

        Chip chip = new Chip();
        chip.Gates = (int)jo["gates"];
        JArray ja = (JArray)jo["truthtable"];

        if (chip.Gates == 1)
        {
            chip.TruthTable = new List<List<bool>>();
            chip.TruthTable.Add(ja.ToObject<List<bool>>());
        }
        else
        {
            chip.TruthTable = ja.ToObject<List<List<bool>>>();
        }

        return chip;
    }

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

若要使用转换器,请在反序列化之前创建一个实例并将其添加到序列化程序的Converters集合中:

代码语言:javascript
复制
serializer.Converters.Add(new ChipConverter());

或者,如果您愿意,可以用[JsonConverter]属性对类进行注释:

代码语言:javascript
复制
[JsonConverter(typeof(ChipConverter))]
class Chip
{
    ...
}

下面是一个演示,展示了转换器的工作情况(注意,我这里使用了JsonConvert.DeserializeObject<T>(),而不是创建JsonSerializer实例,但它的工作方式是相同的):

代码语言:javascript
复制
class Program
{
    static void Main(string[] args)
    {
        string json = @"
        [
            {
                ""gates"": 1,
                ""truthtable"": [ false, true ]
            },
            {
                ""gates"": 2,
                ""truthtable"": [ [ false, false ], [ false, true ] ]
            }
        ]";

        List<Chip> chips = JsonConvert.DeserializeObject<List<Chip>>(json,
                                                         new ChipConverter());

        foreach (Chip c in chips)
        {
            Console.WriteLine("gates: " + c.Gates);
            foreach (List<bool> list in c.TruthTable)
            {
                Console.WriteLine(string.Join(", ",
                    list.Select(b => b.ToString()).ToArray()));
            }
            Console.WriteLine();
        }
    }
}

输出:

代码语言:javascript
复制
gates: 1
False, True

gates: 2
False, False
False, True
票数 2
EN

Stack Overflow用户

发布于 2014-02-21 17:57:11

简单..。将生成可信任(在门== 1情况下)的方法更改为输出数组(或List>)。

“门”:1,“真实”:[假,真]

请记住,您的数据契约中有一个类型,在这种情况下,数据契约需要一个List>,并且发送了一个错误的类型(List<>)。您能在== 1门的情况下编写生成“可信”的代码吗?

PS。对不起,我英语说得不好.=)

票数 0
EN

Stack Overflow用户

发布于 2014-02-21 18:06:47

假设您使用的是.NET 4.0或更高版本,则可以将json反序列化为动态对象

代码语言:javascript
复制
string jsonData = ....; // fill your json data here
dynamic d = JsonConvert.DeserializeObject(jsonData);

然后检查d.truthtable[0]的类型,确定当d.truthtable是数组或嵌套数组时该做什么。

代码语言:javascript
复制
if (d.truthtable != null && d.truthtable.Count > 0)
{
    if (d.truthtable[0].GetType() == typeof(Newtonsoft.Json.Linq.JValue))
    {
        // do something when truthtable is an array
    }
    else if (d.truthtable[0].GetType() == typeof(Newtonsoft.Json.Linq.JArray))
    {
        // do something when truthtable is a nested array
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21940989

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档