Reputation: 325
I am trying to create a JSON file that contains a list of parts for computers.
My Parts Class
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
}
}
First I create a handful of Model, Categories, and Parts.
....
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);
....
This outputs the following json file.
[
{
"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
}
]
I am having trouble doing the reverse. Deserialize the JSON file back into a Part_DB Object. Here is my attempt
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);
}
Upvotes: 0
Views: 1717
Reputation: 18175
I suspect it has something to do with the somewhat oddness of your top-level model actually inheriting from IEnumerable<T>
. I was able to successfully deserialize the file produced into a Part_DB by using the following:
var newObj = JsonConvert.DeserializeObject<List<Part>>( json );
var partDb = new Part_DB();
partDb.Parts.AddRange( newObj );
The json
variable contains the contents of the file, which is actually an array of Part
objects, not a complete Part_DB
object. Then to reconstruct the entire Part_DB
you need to take the deserialized array and add it back into the Parts
collection of the Part_DB
.
If you want to deserialize straight into a Part_DB you're going to have to change your model so that Part_DB
isn't inherited from IEnumerable<T>
.
public class Part_DB
{
public List<Part> Parts = new List<Part>();
}
Then you can just deserialize directly into that type.
JsonConvert.DeserializeObject<Part_DB>( json );
But it will change your JSON a bit.
{
"Parts": [
{
"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
}
]
}
Upvotes: 1
Reputation: 963
I think that for the Json.NET the Part_DB
is just an object (which happens to be enumerable, but that's not important) so it is looking for the JSON that looks more like:
{ "Parts": and here should be your output from serialization}
The output you got from serialization is actually just the serialized List<Part>
so try deserializing to it first, create a new Part_DB object and then assign that list to the Parts property.
Upvotes: 0