2
\$\begingroup\$

I am working with JSON API data in .NET6 and was having trouble de-serializing nested data that has a variable rootname since my class type will never match what's in the JSON string.

{
   "???":{
      "type":"static",
      "description":"n/a",
      "id":null,
      "upc":"s324df",
      "price":1802
   }
}

in the example above "???" equates to whatever is sent in the request so since I know the value, I just modified the JSON string and removed the root and the last "}" so that JsonSerializer will recognize the property names and is no longer looking for a root class with a type of "???". Here is my workaround code:

var response = await _client.GetAsync(api + Symbol);
var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
if (response.IsSuccessStatusCode)
{
    var result = await response.Content.ReadAsStringAsync();
    var temp = result.Remove(0, Symbol.Count() + 4);
    var temp2 = temp.Remove(temp.Count() - 1, 1);
    quote = JsonSerializer.Deserialize(temp2, options);
}

I think this will work fine for what this application is, but feels janky and I am interested learning if there is a better way.

\$\endgroup\$

3 Answers 3

2
\$\begingroup\$

As an alternative you can do the following:

using var jsonParse = JsonDocument.Parse(result); 
var innerNode = jsonParse.RootElement.GetProperty(Symbol);
...

Since you know the symbol that's why you can use the GetProperty method.

\$\endgroup\$
1
\$\begingroup\$

Why not using JsonNode or JsonDocument to parse the JSON then process it before deserializing?.

the easiest way to work with your code is doing this :

if(!string.IsNullOrWhiteSpace(result))
{
    var node = JsonNode.Parse(json).AsObject().FirstOrDefault();
    
    if(node != null)
    {
        quote = node.Value.Deserialize<SomeClass>(options);     
    }
}

Note that there is no TryParse in JsonNode, so you need to consider a way to validate the response to ensure that you get the correct result before parsing and deserializing.

Note: JsonDocument has TryParse that accepts Utf8JsonReader so it might be useful for you to start with.

\$\endgroup\$
0
\$\begingroup\$

The JSON structure should be deserialized as a Dictionary<string, Quote>.

You can do this using System.Text.Json.Serialization and System.Net.Http.Json:

public record class Quote
{
    public string Type { get; init; }
    public string Description { get; init; }
    public long? Id { get; init; }
    public string Upc { get; init; }
    public decimal Price { get; init; }
}

...

var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
var quotes = await _client.GetFromJsonAsync<Dictionary<string, Quote>>(api + Symbol, options);
quote = quotes[Symbol];
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.