I currently have an API request that I make with Avalonia C# and I manage to return the entire JSON as a result but cannot retrieve each element in a foreach.
Here is the current code:
// Get servers infos
private async Task GetServersInfos()
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("GET"), "http://example.com/api"))
{
var response = await httpClient.SendAsync(request);
if (response.IsSuccessStatusCode)
{
string jsonObject = JsonSerializer.Serialize(response.Content);
var results = await response.Content.ReadAsStringAsync();
foreach (var result in results)
{
TestText.Text = result["name"];
}
}
}
}
}
And the JSON result:
{
"1": {
"name": "Example 1",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit...",
},
"2": {
"name": "Example 2",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit...",
}
}
But I have the following error: Unable to apply indexing using [] to an expression of type ‘char’.
2
Answers
ReadAsStringAsync
returns a simple string and not a list of objects.That’s why you can’t iterate over it.
You can create a class for your content and let the serializer create a list of instances of your class and then you can iterate over it in a foreach.
Example:
Possible Business Objects:
Deserialze the to Business Objects:
You must use
JsonSerializer.DeserializeAsync
to convert the known JSON to a C# data type or useJsonDocument
to convert the unknown JSON response to a read-only DOM model and traverse its element nodes.To improve the performance, you should pass a
Stream
toJsonSerializer.SeserializeAsync
as this eliminates one complete enumeration of the response message. To issue a HTTP GET request, simply use one of theGet...
methods provided by theHttpClient
API.In our case we pick the
HttpClient.GetStreamAsync
method.The response message is a single JSON object (and not an array) that is constructed of key-value pairs. That makes a list of key-value pairs. Which is exactly how the
Dictionary
structure is built.That’s a crucial finding as this means we can deserialize every well-formed JSON object into a
Dictionary<string, object>
.The only special case is if the JSON contains an array. In this case we must tell the
JsonSerializer
how to convert it, which means we have to create a customJsonConverter
. In any other case we can always useDictionary<string, string>
to deserialize or serialize a JSON object.However, to handle complex unknown JSON content the recommended way would be to use
JsonDocument
.Example 1
Deserialize a known simple JSON that contains no arrays in a very general manner using
JsonSerializer
(doesn’t require a custom data structure).In your example case we expect a list of nested JSON objects, which can be represented a nested
Dictionary
in the form ofDictionary<string, Dictionary<string, string>>
:Example 2
Deserialize a known JSON that contains no arrays in a very specialized manner using
JsonSerializer
.In your example case we expect a list of nested JSON objects, which enables us to create a C# type for improved convenience in terms of data handling:
DataSet.cs
“c#
public class DataSet
{
public string Name { get; }
public string Description { get; }
}
Example 3
Deserialize an unknown JSON using
JsonDocument
.We can traverse and inspect every JSON using the JSON’s read-only DOM.
If we need to manipulate the JSON document we would use
JsonNode
instead.However,
JsonDocument
seems to be sufficient and it is faster thanJsonNode
: