如何使用Json.Net将JSON数组反序列化为对象?

我有一个有效的JSON对象,里面有一个JSON数组。 JSON数组没有花括号,并且在其中包含逗号分隔的混合类型列表。 它看起来像这样:

{ "ID": 17, "Days": 979, "Start_Date": "10/13/2012", "End_Date": "11/12/2012", "State": "", "Page": 1, "Test": "Valid", "ROWS": [ [441210, "A", "12/31/2009", "OK", "Done", "KELLEY and Co'", "12/31/2009", "06/29/2010", "TEXAS", "Lawyers", 6, "", "Done"], [441151, "B", "12/31/2009", "No", "In-process", "Sage & Co", "12/31/2009", "06/29/2010", "CALIFORNIA", "Realtor", 6, "", "In Process"] ] } 

我已经创建了一个反映JSON结构的类,它有一个复杂数组的List:

 class myModel { public int ID { get; set; } public int Days { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public string State { get; set; } public string Page { get; set; } public string Test { get; set; } List Rows { get; set; } } 

我也用列表列表测试了它:

 List<List> Rows { get; set; } 

这样的孩子模特:

 class ChildModel { public int ID { get; set; } public string StatusId { get; set; } public DateTime ContactDate { get; set; } public string State { get; set; } public string Status { get; set; } public string CustomerName { get; set; } public DateTime WorkStartDate { get; set; } public DateTime WorkEndDate { get; set; } public string Territory { get; set; } public string CustType { get; set; } public int JobOrder { get; set; } public string Filler { get; set; } public string Link { get; set; } } 

在我的program.cs文件中,我将它反序列化为:

 using (StreamReader r = new StreamReader(@"D:\01.json")) { myModel items = JsonConvert.DeserializeObject(r.ReadToEnd()); } 

当我运行此程序时,子对象(行)始终为null 。 我究竟做错了什么?

Json.Net没有自动将数组映射到类的工具。 为此,您需要一个自定义的JsonConverter 。 这是一个适用于您的通用转换器。 它使用自定义[JsonArrayIndex]属性来标识类中的哪些属性对应于数组中的哪些索引。 如果JSON更改,这将允许您轻松更新模型。 此外,您可以安全地省略您不需要的类中的属性,例如Filler

这是代码:

 public class JsonArrayIndexAttribute : Attribute { public int Index { get; private set; } public JsonArrayIndexAttribute(int index) { Index = index; } } public class ArrayToObjectConverter : JsonConverter where T : class, new() { public override bool CanConvert(Type objectType) { return objectType == typeof(T); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JArray array = JArray.Load(reader); var propsByIndex = typeof(T).GetProperties() .Where(p => p.CanRead && p.CanWrite && p.GetCustomAttribute() != null) .ToDictionary(p => p.GetCustomAttribute().Index); JObject obj = new JObject(array .Select((jt, i) => { PropertyInfo prop; return propsByIndex.TryGetValue(i, out prop) ? new JProperty(prop.Name, jt) : null; }) .Where(jp => jp != null) ); T target = new T(); serializer.Populate(obj.CreateReader(), target); return target; } public override bool CanWrite { get { return false; } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } } 

要使用转换器,您需要标记ChildModel类,如下所示:

 [JsonConverter(typeof(ArrayToObjectConverter))] class ChildModel { [JsonArrayIndex(0)] public int ID { get; set; } [JsonArrayIndex(1)] public string StatusId { get; set; } [JsonArrayIndex(2)] public DateTime ContactDate { get; set; } [JsonArrayIndex(3)] public string State { get; set; } [JsonArrayIndex(4)] public string Status { get; set; } [JsonArrayIndex(5)] public string CustomerName { get; set; } [JsonArrayIndex(6)] public DateTime WorkStartDate { get; set; } [JsonArrayIndex(7)] public DateTime WorkEndDate { get; set; } [JsonArrayIndex(8)] public string Territory { get; set; } [JsonArrayIndex(9)] public string CustType { get; set; } [JsonArrayIndex(10)] public int JobOrder { get; set; } [JsonArrayIndex(12)] public string Link { get; set; } } 

然后像往常一样反序列化,它应该按照你想要的方式工作。 这是一个演示: https : //dotnetfiddle.net/n3oE3L

注意:我没有实现WriteJson ,因此如果将模型序列化为JSON,它将不会序列化为数组格式; 相反,它将使用默认对象序列化。

使用它将数据反序列化为json对象…

 public class Rootobject { public int ID { get; set; } public int Days { get; set; } public string Start_Date { get; set; } public string End_Date { get; set; } public string State { get; set; } public int Page { get; set; } public string Test { get; set; } public object[][] ROWS { get; set; } } 

…然后创建一个实用程序函数,将object[][]转换为您想要的目标对象……

(使用visual studio创建:编辑 – >选择性粘贴 – > JSON类)