0

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

2
  • class KipReport<T>{ public IList<T> Data { get; set; } }. and JsonConvert.DeserializeObject<KipReport<fooBar>>(responseBody) ? something like this to pass the type Commented Mar 5, 2021 at 9:13
  • Do you know the type of Data to expect before you deserialize the JSON, or do you only find out what it is after you deserialize it and look at the reportID? Commented Mar 5, 2021 at 17:48

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

You can also public T Data { get; set; }, so you will be able to handle what ever result you have: string, List<string>, customType, List<CustomType> JsonConvert.DeserializeObject<WrapperType<string>>("{\"Data\":\"This is not an array nor a object\"}");
Sorry its saying Type or Namespace T could not be found
class KipReport<T> not class KipReport
0

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"

1 Comment

why not use a json deserializing library like newton soft

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.