0

I am looking for a mechanism in the System.Text.Json package, where I would be able to deserialize JSON on partially matching property names. Unfortunately, the API that I am writing a client for responds with different property names depending on the request query parameters.

First example:

Request url: ?[..]&interval=5min

{
    "Meta Data": {
        "1. Information": "Intraday (5min) open, high, low, close prices and volume",
        "2. Symbol": "IBM",
        "3. Last Refreshed": "2022-04-26 19:55:00",
        [..]
    },
    "Time Series (5min)": {
        "2022-04-26 19:55:00": {
            "1. open": "136.3800",
            "2. high": "136.3800",
            "3. low": "136.3800",
            "4. close": "136.3800",
            "5. volume": "250"
        },
        [..]
    }
}

Request url: ?[..]&interval=10min

{
    "Meta Data": {
        "1. Information": "Intraday (10min) open, high, low, close prices and volume",
        "2. Symbol": "IBM",
        "3. Last Refreshed": "2022-04-26 19:55:00",
        [..]
    },
    "Time Series (10min)": {
        "2022-04-26 19:55:00": {
            "1. open": "136.3800",
            "2. high": "136.3800",
            "3. low": "136.3800",
            "4. close": "136.3800",
            "5. volume": "250"
        },
        [..]
    }
}

Is there an easy way to circumvent this and deserialize JSON based on partially matching property names?

dbc
  • 104,963
  • 20
  • 228
  • 340
phoenix
  • 365
  • 1
  • 4
  • 15

2 Answers2

1

I would suggest another way of solving this, instead of fiddling with the actual json parser.

The actual problem seems to be the API not answering correctly, that would optimally be the place to fix this. If that is out of question for some reason I would recommend implementing a kind of pre-deserializer on client site, that fixes the partially matching names to be the correct names. After that you pass the corrected json into the normal parser.

You could even improve on the json structure you receive this way by looking for "Time Series (xxxx)" and adding the time info into the structure as a new attribute. Same with the date and time.

That way you do not make your project dependend on some specialized json parser but rather fix the problem as close to the root as you can.

Eskapone
  • 321
  • 1
  • 7
0

Try JsonDocument.
In it, you can access properties both by name and by enumeration.

using System.Text.Json;

var json = File.ReadAllText("test.json");
var doc = JsonDocument.Parse(json);

var metaData = doc.RootElement.GetProperty("Meta Data");
Console.WriteLine(metaData.GetProperty("1. Information"));
Console.WriteLine(metaData.GetProperty("2. Symbol"));
Console.WriteLine(metaData.GetProperty("3. Last Refreshed"));
Console.WriteLine();

var timeSeries = doc.RootElement.EnumerateObject().Skip(1).First();
Console.WriteLine(timeSeries.Name);
Console.WriteLine();

foreach (var item in timeSeries.Value.EnumerateObject())
{
    Console.WriteLine(item.Name);
    var value = item.Value;
    Console.WriteLine(value.GetProperty("1. open"));
    Console.WriteLine(value.GetProperty("2. high"));
    Console.WriteLine(value.GetProperty("3. low"));
    Console.WriteLine(value.GetProperty("4. close"));
    Console.WriteLine(value.GetProperty("5. volume"));
    Console.WriteLine();
}
Alexander Petrov
  • 13,457
  • 2
  • 20
  • 49