简体   繁体   中英

Deserialize JSON string when there is dynamic type JSON array in that object

I have a JSON string like this

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

Here is my class structure for that

 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; }
    }

Here the Data part I cant specify a constant type because it may change from report to report... I some other reports data will be like

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

So I have different classes for these Data part

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}
}

This is how I deserialize using Newtonsoft

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

So once the rpt is deserialized (works fine) I have a switch case in which i am taking the Data part into corresponding object

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;

}

But its not at all working and this is the error

Unable to cast object of type 'Newtonsoft.Json.Linq.JArray' to type 'System.Collections.Generic.List`1[common.ProjectS]'.

So what I did wrong or how can I make it work

I suggest you make the KipReport generic.

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
}  

When you deserialize, specify the type:
JsonConvert.DeserializeObject<KipReport<project>>(responseBody);
JsonConvert.DeserializeObject<KipReport<Employee>>(responseBody);

If you want to know the type before deserializing, so that you know which deserialization to perform, maybe perform a string check by some keyword beforehand.

You can try to do this way:

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

Example:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM