json.net无法反序列化为对象列表

时间:2014-04-18 22:35:09

标签: c# json.net

我正在尝试创建一个包含计算机部件列表的JSON文件。

我的零件类

namespace Part_Class
{
    public class Part_DB : IEnumerable<Part>
    {
        public List<Part> Parts = new List<Part>();

        public IEnumerator<Part> GetEnumerator()
        {
            return this.Parts.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }

    public class Model
    {
        public String Name { get; set; } // E6430, M4600, T4220

        public Model(string Name)
        {
            this.Name = Name;
        }
    }

    public class Category
    {
        public String Name { get; set; } // E6430, M4600, T4220

        public Category(string Name)
        {
            this.Name = Name;
        }
    }

    public class Part
    {
        public List<Model> Models = new List<Model>(); //E6420
        public string PartNumber { get; set; } //PPHPX, UK717
        public string Description { get; set; } // "320GB Hard Drive", "E6410 keyboard"
        public List<Category> Categories = new List<Category>(); //Hard Drive, Keyboard 
        public bool HeroKit { get; set; } //Y or N
    }
}

首先,我创建了一些模型,类别和零件。

....
Model E6410 = new Model("E6410");
Model M4600 = new Model("M4600");
Model M4700 = new Model("M4700");

Category Keyboard = new Category("Keyboard");
Category Hard_Drive = new Category("Hard Drive");

Part PPHPX = new Part();
PPHPX.PartNumber = "PPHPX";
PPHPX.Models.Add(M4600);
PPHPX.Models.Add(M4700);
PPHPX.Description = "320GB Spindle Hard Drive";
PPHPX.Categories.Add(Hard_Drive);
PPHPX.HeroKit = true;

Part UK717 = new Part();
UK717.PartNumber = "UK717";
UK717.Models.Add(E6410);
UK717.Description = "102 Key Non Backlit";
UK717.Categories.Add(Keyboard);
UK717.HeroKit = true;

//I store those parts into a Part_DB Object
Part_DB Stored = new Part_DB();
Stored.Parts.Add(PPHPX);
Stored.Parts.Add(UK717);

//Then take that object and serialize it into a string
string jsonStr = JsonConvert.SerializeObject(Stored, Formatting.Indented);  

//Then save it to a file
System.IO.File.WriteAllText(@"C:\****\Parts.json", jsonStr);
....

这将输出以下json文件。

[
  {
    "Models": [
      {
        "Name": "M4600"
      },
      {
        "Name": "M4700"
      }
    ],
    "Categories": [
      {
        "Name": "Hard Drive"
      }
    ],
    "PartNumber": "PPHPX",
    "Description": "320GB Spindle Hard Drive",
    "HeroKit": true
  },
  {
    "Models": [
      {
        "Name": "E6410"
      }
    ],
    "Categories": [
      {
        "Name": "Keyboard"
      }
    ],
    "PartNumber": "UK717",
    "Description": "102 Key Non Backlit",
    "HeroKit": true
  }
]

我在反向时遇到了麻烦。将JSON文件反序列化为Part_DB对象。这是我的尝试

List<string> errors = new List<string>();

try
{
    //Create a string of the JSON File
    string jsonStr;
    using (StreamReader file = File.OpenText(@"C:\****\Parts.json"))
    {
        jsonStr = file.ReadToEnd();
    }

    // Deserilize object into the Part_DB
    Part_DB Stored = JsonConvert.DeserializeObject<Part_DB>(jsonStr,
        new JsonSerializerSettings
        {
            Error = delegate(object senders, Newtonsoft.Json.Serialization.ErrorEventArgs args)
            {
                errors.Add(args.ErrorContext.Error.Message);
                //Debug.WriteLine(args.ErrorContext.Error.Message);
                args.ErrorContext.Handled = true;
            },
        });
}
catch (Exception ex) {
    Console.WriteLine(ex);
}

2 个答案:

答案 0 :(得分:1)

我怀疑它与您从IEnumerable<T>继承的顶级模型有些奇怪有关。通过使用以下命令,我能够成功地将生成的文件反序列化为Part_DB:

var newObj = JsonConvert.DeserializeObject<List<Part>>( json );
var partDb = new Part_DB();
partDb.Parts.AddRange( newObj );

json变量包含文件的内容,实际上是Part个对象的数组,而不是完整的Part_DB对象。然后重新构建您需要采用反序列化数组的整个Part_DB,并将其重新添加回Parts的{​​{1}}集合中。

如果您想直接反序列化为Part_DB,则必须更改模型,以便Part_DB不会继承Part_DB

IEnumerable<T>

然后您可以直接反序列化为该类型。

public class Part_DB
{
    public List<Part> Parts = new List<Part>();
}

但它会改变你的JSON。

JsonConvert.DeserializeObject<Part_DB>( json );

答案 1 :(得分:0)

我认为对于Json.NET来说,Part_DB只是一个对象(碰巧是可枚举的,但这并不重要)所以它正在寻找看起来更像的JSON: / p>

{ "Parts": and here should be your output from serialization}

从序列化获得的输出实际上只是序列化的List<Part>所以首先尝试反序列化,创建一个新的Part_DB对象,然后将该列表分配给Parts属性。