Search code examples
c#restsharpjson-deserialization.net-4.8system.text.json

How to deserialize json array of objects into object with properties?


I am working with the following JSON string from api response:

{
    "points": [{
            "name": "title",
            "value": "Test"
        }, {
            "name": "category",
            "value": null
        }, {
            "name": "created",
            "value": 1550743894373
        }, {
            "name": "version",
            "value": 1
    }]
}

the json-structure of the response is always the same, root-node "points" has 1 or more name-value pairs.

I have a class structure as follows for parsing and filling the json data

// can't use record, have to use class, i only have .NET Framework 4.8 available
public class Point
{
    [JsonPropertyName("name")]
    public string Name { get; set; }

    [JsonPropertyName("value")]
    public object Value { get; set; }
}

public class MyViews
{
    [JsonPropertyName("points")]
    public List<Point> Points { get; set; }
}

and this is my code:

using RestSharp;

// create request for API
var request = new RestRequest("my-views");

// get response from API with deserialized json-data to my Points-object
var response = await client.ExecuteGetAsync<MyViews>(request);

// just example of getting simple data from object
Point response_point = response.Data.Points.first(); // get first object
string title;
// check if object is a title
if (response_point.Name == "title") {
    title = response_point.Value; // get value of title
}}

// my goal is:
// Point response_point = response.Data;
// title = response_point.title;

My deserialization goal is to fill data in the following class structure:

public class Point
{
    public string title { get; set; }
    public string category { get; set; }
    public DateTime? created { get; set; }
    public int? version { get; set; }    
}

I want to have only one "Point" object with all name-value pairs as properties (without List in MyViews class).

Is there a way to transform the data on deserialization process, or trigger a method on Points-object after deserialization complete?

I'm using RestSharp-lib with default serializer System.Text.Json.

Thanks.

UPDATE: I'm not attached to any library, I have free choice, the only restriction I have to stick to is .NET 4.8 Framework.


Solution

  • Text.Json and Net 4.8 is the worst combination ever. Install Newtonsoft.Json and the code will be simpler.

    using Newonsoft.Json;
    
    var response = await client.ExecuteGetAsync(request);
    
    var points = JObject.Parse(response.Content)["points"];
    
    Point point = new Point();
    
    foreach (var item in points)
    {
        var val = item["value"];
        switch ((string)item["name"])
        {
            case "title": point.title = (string)val; break;
            case "category": point.category = (string)val; break;
            // case "created":point.created = (DateTime) val; break; //only you know what format is your date
            case "version": point.version = (int?)val; break;
        }
    }