如何对具有不同名称的对象数组进行反序列化?

约翰

在使用C#的Windows Phone应用中,我尝试使用以下结构反序列化一些JSON:

[ { "kite" : { "supplier" : "ABC",
        "currency" : "GBP",
        "cost" : "7.98"
      } },
  { "puzzle" : { "supplier" : "DEF",
        "currency" : "USD",
        "cost" : "7.98"
      } },
  { "ball" : { "supplier" : "DEF",
        "currency" : "USD",
        "cost" : "5.49"
      } }
]

这是玩具列表,其中的玩具(风筝,拼图,球)的名称事先未知。我对JSON的格式没有任何控制。

使用json2csharp.com我得到以下类:

public class Kite
{
    public string supplier { get; set; }
    public string currency { get; set; }
    public string cost { get; set; }
}

public class Puzzle
...

public class Ball
...

public class RootObject
{
    public Kite kite { get; set; }
    public Puzzle puzzle { get; set; }
    public Ball ball { get; set; }
}

在我看来,这看起来像“玩具”对象的数组,但是我不知道在反序列化时采取什么方法。

我曾经工作过的唯一代码是基本代码:

var root = JsonConvert.DeserializeObject(rawJSON);

我认为类似以下内容的方法可能会起作用,但如果该玩具有效(并且无效),我将丢失该玩具的名称:

public class Toy
{
    public string supplier { get; set; }
    public string currency { get; set; }
    public string cost { get; set; }
}
List<Toy> toyList = (List<Toy>) JsonConvert.DeserializeObject(rawJSON, typeof(List<Toy>));

有什么建议吗?

布赖恩·罗杰斯

你近了 如果您Toy在问题中定义班级,则可以反序列化为List<Dictionary<string, Toy>>因此,每个玩具实际上由一个Dictionary具有单个条目的a表示Key是玩具的名称,ValueToy信息。
这是一个演示:

string json = @"
[ { ""kite"" : { ""supplier"" : ""ABC"",
        ""currency"" : ""GBP"",
        ""cost"" : ""7.98""
      } },
  { ""puzzle"" : { ""supplier"" : ""DEF"",
        ""currency"" : ""USD"",
        ""cost"" : ""7.98""
      } },
  { ""ball"" : { ""supplier"" : ""DEF"",
        ""currency"" : ""USD"",
        ""cost"" : ""5.49""
      } }
]";

List<Dictionary<string, Toy>> list = 
       JsonConvert.DeserializeObject<List<Dictionary<string, Toy>>>(json);

foreach (Dictionary<string, Toy> dict in list)
{
    KeyValuePair<string, Toy> kvp = dict.First();
    Console.WriteLine("toy: " + kvp.Key);
    Console.WriteLine("supplier: " + kvp.Value.Supplier);
    Console.WriteLine("cost: " + kvp.Value.Cost + " (" + kvp.Value.Currency + ")");
    Console.WriteLine();
}

输出以下内容:

toy: kite
supplier: ABC
cost: 7.98 (GBP)

toy: puzzle
supplier: DEF
cost: 7.98 (USD)

toy: ball
supplier: DEF
cost: 5.49 (USD)

诚然,这种解决方案有点“笨拙”,因为最好将玩具的名称包含在Toy类本身中,而不要进行干预Dictionary有两种方法可以解决此问题。一种方法是NameToy添加一个属性,将其反序列化为与上述相同的结构,然后进行一些后期处理,以将名称从每个名称移至相应的名称,Dictionary在此过程中Toy构建一个新名称List<Toy>第二种方法是创建一个自定义,JsonConverter以在反序列化期间处理此转换。如果您愿意,我很乐于演示这些替代方法中的任何一种。请让我知道。如果您只需要快捷的方法,那么上面的方法应该可以解决。

使用自定义JsonConverter的替代方法

这种方法有点“清洁”,因为我们可以将所有Toy信息放在一个强类型的对象上,并且将所有反序列化逻辑保持分开,以免使主代码混乱。

首先,我们需要更改您的Toy课程以为其提供Name属性。

class Toy
{
    public string Name { get; set; }
    public string Supplier { get; set; }
    public string Currency { get; set; }
    public decimal Cost { get; set; }
}

接下来,我们创建一个继承自的类JsonConverter

class ToyConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        // This lets JSON.Net know that this converter can handle Toy objects
        return (objectType == typeof(Toy));
    }

    public override object ReadJson(JsonReader reader, 
        Type objectType, object existingValue, JsonSerializer serializer)
    {
        // load the toy JSON object into a JObject
        JObject jo = JObject.Load(reader);

        // get the first (and only) property of the object
        JProperty prop = jo.Properties().First();

        // deserialize the value of that property (which is another
        // object containing supplier and cost info) into a Toy instance
        Toy toy = prop.Value.ToObject<Toy>();

        // get the name of the property and add it to the newly minted toy
        toy.Name = prop.Name;

        return toy;
    }

    public override void WriteJson(JsonWriter writer, 
        object value, JsonSerializer serializer)
    {
        // If you need to serialize Toys back into JSON, then you'll need
        // to implement this method.  We can skip it for now.
        throw new NotImplementedException();
    }
}

要使用转换器,我们只需要创建一个实例并将其传递给即可DeserializeObject<T>()现在有了转换器,我们可以直接反序列化为List<Toy>,这很自然。

List<Toy> toys = JsonConvert.DeserializeObject<List<Toy>>(json, new ToyConverter());

从那里访问玩具数据很简单。

foreach (Toy toy in toys)
{
    Console.WriteLine("toy: " + toy.Name);
    Console.WriteLine("supplier: " + toy.Supplier);
    Console.WriteLine("cost: " + toy.Cost + " (" + toy.Currency + ")");
    Console.WriteLine();
}

您会注意到,它给出的输出与上一个示例完全相同,但是代码更加简洁。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

反序列化具有不同名称的属性?

来自分类Dev

在Jackson中反序列化具有相同名称但类型不同的属性?

来自分类Dev

从不同元素中反序列化具有相同名称的xml属性

来自分类Dev

是否可以反序列化和序列化具有不同属性名称的json对象?

来自分类Dev

反序列化具有不同结构和名称的json对象

来自分类Dev

当嵌套对象具有名称空间时如何反序列化XML

来自分类Dev

当嵌套对象具有名称空间时如何反序列化XML

来自分类Dev

在C#中反序列化具有相同名称的多个XML元素

来自分类Dev

如何反序列化具有两个名称相同但元素具有不同数据类型的XML?

来自分类Dev

使用具有不同元素名称的同一对象反序列化Xml

来自分类Dev

如何序列化和反序列化具有正确格式的数组

来自分类Dev

如何序列化和反序列化具有正确格式的数组

来自分类Dev

如何在派生类中序列化具有不同名称的基类变量

来自分类Dev

反序列化具有对象 ID 作为对象名称的 JSON 对象列表

来自分类Dev

将具有相同名称的不同xml元素反序列化为不同的C#类

来自分类Dev

如何序列化具有相同复杂prop类型但名称不同的对象

来自分类Dev

序列化具有相同名称但不同属性的2个属性

来自分类Dev

具有不同属性的相同属性名称的Json反序列化

来自分类Dev

反序列化可以具有不同类型的属性名称

来自分类Dev

在C#中反序列化具有不同类型名称的XML元素

来自分类Dev

具有多个名称相同但内容不同的元素的 XML 反序列化

来自分类Dev

Gson将字段反序列化为具有不同名称的变量,尽管具有具有字段名称的变量

来自分类Dev

使用Jackson反序列化包装在具有未知属性名称的对象中的JSON

来自分类Dev

反序列化不同对象类型的数组

来自分类Dev

具有多个名称空间的XML反序列化

来自分类Dev

为每个键值反序列化具有不同对象类型的JSON文件

来自分类Dev

反序列化具有不同类型的JSON数组

来自分类Dev

JQUERY:如何序列化具有相同名称的输入字段

来自分类Dev

反序列化具有不同属性的 JSON

Related 相关文章

  1. 1

    反序列化具有不同名称的属性?

  2. 2

    在Jackson中反序列化具有相同名称但类型不同的属性?

  3. 3

    从不同元素中反序列化具有相同名称的xml属性

  4. 4

    是否可以反序列化和序列化具有不同属性名称的json对象?

  5. 5

    反序列化具有不同结构和名称的json对象

  6. 6

    当嵌套对象具有名称空间时如何反序列化XML

  7. 7

    当嵌套对象具有名称空间时如何反序列化XML

  8. 8

    在C#中反序列化具有相同名称的多个XML元素

  9. 9

    如何反序列化具有两个名称相同但元素具有不同数据类型的XML?

  10. 10

    使用具有不同元素名称的同一对象反序列化Xml

  11. 11

    如何序列化和反序列化具有正确格式的数组

  12. 12

    如何序列化和反序列化具有正确格式的数组

  13. 13

    如何在派生类中序列化具有不同名称的基类变量

  14. 14

    反序列化具有对象 ID 作为对象名称的 JSON 对象列表

  15. 15

    将具有相同名称的不同xml元素反序列化为不同的C#类

  16. 16

    如何序列化具有相同复杂prop类型但名称不同的对象

  17. 17

    序列化具有相同名称但不同属性的2个属性

  18. 18

    具有不同属性的相同属性名称的Json反序列化

  19. 19

    反序列化可以具有不同类型的属性名称

  20. 20

    在C#中反序列化具有不同类型名称的XML元素

  21. 21

    具有多个名称相同但内容不同的元素的 XML 反序列化

  22. 22

    Gson将字段反序列化为具有不同名称的变量,尽管具有具有字段名称的变量

  23. 23

    使用Jackson反序列化包装在具有未知属性名称的对象中的JSON

  24. 24

    反序列化不同对象类型的数组

  25. 25

    具有多个名称空间的XML反序列化

  26. 26

    为每个键值反序列化具有不同对象类型的JSON文件

  27. 27

    反序列化具有不同类型的JSON数组

  28. 28

    JQUERY:如何序列化具有相同名称的输入字段

  29. 29

    反序列化具有不同属性的 JSON

热门标签

归档