I am working on a C# app that fetches data from an API. The response from the API has blocks that contain a node Data
that changes in structure and only shares one attribute, Type
. I am using Newtonsoft. How can I deserialize the Data
node to the exact class based on the Type
attribute? So that if I create an items array, when I query the array I can switch on the Type
attribute and know which object maps to it.
The JSON response from the API looks like this:
{
"nextLink": "NextLink",
"value": [
{
"Block": {
"BlockName": "Name",
"BlockClass": "Class",
"IsVisibile": true,
"Data": {
"Type": "Footer",
"Values": [
{
"Property1": "Property1",
"Property2": "Property2"
}
],
"Show": false
}
}
},
{
"Block": {
"BlockName": "Name",
"BlockClass": "Class",
"IsVisibile": true,
"Data": {
"Type": "Header",
"Title": "Main title",
"Subtitle": "Subtitle"
}
}
},
{
"Block": {
"BlockName": "Name",
"BlockClass": "Class",
"IsVisibile": true,
"Data": {
"Type": "Body",
"Information": "Info",
"AdditionalText": "More text",
"Projects": [
"Project1",
"Project2"
]
}
}
}
]
}
These are the classes I have defined based on the API response:
public class Blocks
{
public string NextLink { get; set; }
public Response[] Value { get; set; }
}
public class Response
{
public Block Block { get; set; }
}
public class Block
{
public string BlockName { get; set; }
public string BlockClass { get; set; }
public bool IsVisible { get; set; }
public Data Data { get; set; }
}
public class Data
{
public string Type { get; set; }
???
}
public class FooterType
{
public bool Show { get; set; }
public object[] Values { get; set; }
}
public class HeaderType
{
public string Title { get; set; }
public string Subtitle { get; set; }
}
public class BodyType
{
public string Information { get; set; }
public string AdditionalText { get; set; }
public object[] Projects { get; set; }
}
If I deserialize the response to the specific Type (like below) it of course works for that node in the JSON but not all of them.
public class Data
{
public string Type { get; set; }
public string Title { get; set; }
public string Subtitle { get; set; }
}
How can I deserialize each item in the JSON to the specific type it maps to?
3
Answers
Combined @Martin and @Serge's solution with this. Thanks for the help here.
You can accomplish this by writing your own converter which is doing the class selection
Here is the working example for your case in dotnetfiddle
The simpliest way is to create the polymorphic clases and use a json property constructor
but if you have a lot of json of this kind, instead of adding one line to a constructor you can create a json property converter