Fabricio Rodriguez
Fabricio Rodriguez

Reputation: 4239

Deserializing variable JSON data

In a .NET 4.8 C# application, I'm calling a REST API which returns JSON data as follows:

{
  "pagination": {
    "perPage": 10,
    "currentPage": 1,
    "totalPages": 1,
    "totalRecords": 0
  },
  "links": {
    "first": "https://api.propertyinspect.com/inspections?page=1",
    "prev": null,
    "self": "https://api.propertyinspect.com/inspections?page=1",
    "next": null,
    "last": "https://api.propertyinspect.com/inspections?page=1",
  },
  "data": []
}

The problem lies in the fact that the third field, "data", is variable, and contains different JSON models depending on which endpoint I've called. I thought that I could deserialize this model into the following C# class:

public class Pagination
{
    public int PerPage { get; set; }
    public int CurrentPage { get; set; }
    public int TotalPages { get; set; }
    public int TotalRecords { get; set; }
}

public class Link
{
    public string First { get; set; }
    public string Prev { get; set; }
    public string Self { get; set; }
    public string Next { get; set; }
    public string Last { get; set; }
}

public class PIPagination
{
    public Pagination Pagination { get; set; }
    public Link Links { get; set; }
    public ICollection<object> Data { get; set; }
}

And then, depending on what data type I'm expecting "data" to hold, I would then cast it to that data type. The problem is that I'm not sure how to do the casting.

For example, when calling a certain endpoint, "data" holds an array of "Client" models. So I tried casting like this:

List<Client> clients = pagination.Data.Cast<Client>();

and like this:

List<Client> clients = List<Client>pagination.Data;

but it's not working. Is it even possible to cast from a collection of object to a collection of another type? Or should I rather create various Pagination classes, one for each type of "data"?

Upvotes: 1

Views: 58

Answers (2)

react_33
react_33

Reputation: 11

if you have limited amount of different models then add a constructor for each model like:

if you wanna casts accepted data to List<PIClient> then add into PIClient class

PIClient(dynamic model){
   Id = model.id      // or whatever field name is in json
}

and then

var data = model.Data.Select(x=> new PIClient(x)).ToList();

Upvotes: 1

Jamiec
Jamiec

Reputation: 136114

You should use generics for this - whereby you can reuse most of your classes, and just have different implementations for data

public class Pagination
{
    public int PerPage { get; set; }
    public int CurrentPage { get; set; }
    public int TotalPages { get; set; }
    public int TotalRecords { get; set; }
}

public class Link
{
    public string First { get; set; }
    public string Prev { get; set; }
    public string Self { get; set; }
    public string Next { get; set; }
    public string Last { get; set; }
}

public class PIPagination<TData>
{
    public Pagination Pagination { get; set; }
    public Link Links { get; set; }
    public ICollection<TData> Data { get; set; }
}

This way you might implement a class for Client, and when you try to deserialize that you use PIPagination<Client> as the type.

Upvotes: 3

Related Questions