2014-04-18 3 views
0

컴퓨터 용 부품 목록이 포함 된 JSON 파일을 만들려고합니다.json.net 객체 목록에 직렬화 할 수 없습니다.

내 부품 클래스

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 객체로 역 직렬화합니다. 여기가 Json.NET의 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); 
} 
+1

예외는 무엇입니까? –

답변

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 전체를 다시 구성하려면 비 직렬화 된 배열을 가져와 Part_DB 컬렉션 Parts 컬렉션에 다시 추가해야합니다.

Part_DB로 직접 deserialize하려는 경우 Part_DBIEnumerable<T>에서 상속받지 않도록 모델을 변경해야합니다.

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

그런 다음 해당 유형으로 직접 deserialize 할 수 있습니다.

JsonConvert.DeserializeObject<Part_DB>(json); 

하지만 JSON이 약간 변경됩니다.

{ 
    "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 
    } 
    ] 
} 
+0

감사합니다. 요령은 Part_DB의 IEnumerable 에서 상속을 제거하는 것이 었습니다. 파트를 반복 할 필요가 있지만 Part_DB의 파트의 List Propery는이를 상속받습니다. 따라서'foreach (Stored.Parts에있는 Part P) {Console.WriteLine (P.PartNumber);}'잘 작동합니다. – GerritVK

0

입니다 (열거 될 일이,하지만 그건 중요하지 않아) 그래서 더처럼 보이는 JSON을 찾고있다 :

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

직렬화에서받은 출력은 직렬화 List<Part>이 때문에 부품 속성에 그 목록을 할당 한 다음 새 Part_DB 객체를 생성, 처음에 직렬화 복원 시도하고 사실이다.