当该对象中存在动态类型 JSON 数组时反序列化 JSON 字符串

问题描述

我有一个像这样的 JSON 字符串

{
Success :1,PageNumber :1,TotalPages :5,Data:[{projectName:'Pr1',ProjectId:'p3452'},{projectName:'Pr2',ProjectId:'p5485'}....]
}

这是我的类结构

 public class KipReport
    {
        public bool Success { get; set; }
        public int PageNumber { get; set; }
        public int RecordsPerPage { get; set; }
        public int TotalPages { get; set; }
        public int TotalRecords { get; set; }
        public object Data { get; set; }
    }

这里的数据部分我不能指定一个常量类型,因为它可能会因报告而变化......我其他一些报告数据会像

{
reportID:33,pageNumber:1,totalPages:15,Data:[{EmpName:'EMP1',Department:'R&D',EmpId:234},{EmpName:'Emp2',Department:'Software Development',EmpId:366}....]
}

所以我为这些数据部分设置了不同的类

class project{
public string ProjectId{get;set;}
public string ProjectName{get;set}
}

class Employee{
public string EmpName{get;set;}
publis string EmpId{get;set;}
public string Department{get;set}
}

这就是我使用 Newtonsoft 反序列化的方式

rpt = JsonConvert.DeserializeObject<KipReport>(responseBody);

因此,一旦 rpt 被反序列化(工作正常),我就有了一个开关盒,我将数据部分放入相应的对象中

Switch(reportid){
 case 1:
    List<Project> jsonPS = new List<Project>();
    jsonPS =(List<Project>)rpt.Data;
    break;
  case 2:
    List<Employee> jsonPS = new List<Employee>();
    jsonPS =(List<Employee>)rpt.Data;
    break;

}

但它根本不起作用,这是错误

无法将类型为“Newtonsoft.Json.Linq.JArray”的对象转换为类型 'System.Collections.Generic.List`1[common.ProjectS]'。

那么我做错了什么或者我怎样才能让它工作

解决方法

我建议您将 KipReport 设为通用。

public class KipReport<T>
{
    public bool Success { get; set; }
    public int PageNumber { get; set; }
    public int RecordsPerPage { get; set; }
    public int TotalPages { get; set; }
    public int TotalRecords { get; set; }
    public IList<T> Data { get; set; } // Also note here,it is a List,not a single object
}  

反序列化时,指定类型:
JsonConvert.DeserializeObject<KipReport<project>>(responseBody);
JsonConvert.DeserializeObject<KipReport<Employee>>(responseBody);

如果你想在反序列化之前知道类型,以便你知道要执行哪个反序列化,可以事先通过一些关键字进行字符串检查。

,

您可以尝试这样做:

var result = rpt.Data.OfType<Employee>();
var result2 = rpt.Data.OfType<project>();

示例:

object[] obj = { 1,"2" };
var result = obj.OfType<string>();
// result = "2"