Reputation: 134
Dealing with a JSON response similar to this, some of these responses can be up to 500+ items.
{
"name1": "Paul",
"address1": "123 paul lane",
"name2": "George",
"address2": "123 george lane",
"name3": "Howie",
"address3": "123 howie lane"
}
I would like a way, preferably using some sort of JSON deserialization, to jam this into a list of the following object.
public class Person
{
public string Name { get; set; }
public string Address { get; set; }
}
I'm not opposed to writing a custom deserializer, but I am dealing with quite a few of these types of responses, and a reusable solution would be ideal here.
Upvotes: 0
Views: 392
Reputation: 2020
That looks like a very badly formatted JSON indeed.
My approach would depend on how predictable the fields are in the JSON, but if it is an endless list of key-value pairs without a pattern, I'd probably try to convert it to exactly that.
Your approach will differ if the file is large or small, depending on how much memory you can afford to use for the parsing of this file.
See Read JSON with JsonTextReader.
string json = "{\"name1\": \"Paul\",\"address1\": \"123 paul lane\",\"name2\": \"George\",\"address2\": \"123 george lane\",\"name3\": \"Howie\",\"address3\": \"123 howie lane\"}";
using var reader = new Newtonsoft.Json.JsonTextReader(new System.IO.StringReader(json));
while (reader.Read())
{
switch (reader.TokenType)
{
case Newtonsoft.Json.JsonToken.PropertyName:
case Newtonsoft.Json.JsonToken.String:
Console.WriteLine($"{reader.TokenType} - {reader.Value}");
break;
default:
Console.WriteLine($"Skipped: {reader.TokenType}");
break;
}
}
See Use Utf8JsonReader.
string json = "{\"name1\": \"Paul\",\"address1\": \"123 paul lane\",\"name2\": \"George\",\"address2\": \"123 george lane\",\"name3\": \"Howie\",\"address3\": \"123 howie lane\"}";
var data = System.Text.Encoding.UTF8.GetBytes(json);
var reader = new System.Text.Json.Utf8JsonReader(data);
while (reader.Read())
{
switch (reader.TokenType)
{
case System.Text.Json.JsonTokenType.PropertyName:
case System.Text.Json.JsonTokenType.String:
Console.WriteLine($"{reader.TokenType} - {reader.GetString()}");
break;
default:
Console.WriteLine($"Skipped: {reader.TokenType}");
break;
}
}
Both examples above will output:
Skipped: StartObject
PropertyName - name1
String - Paul
PropertyName - address1
String - 123 paul lane
PropertyName - name2
String - George
PropertyName - address2
String - 123 george lane
PropertyName - name3
String - Howie
PropertyName - address3
String - 123 howie lane
Skipped: EndObject
If the JSON file is small, you could parse the entire file into a JObject and iterate through it like that.
private static IEnumerable<KeyValuePair<string, string>> GetPairs()
{
string json = "{\"name1\": \"Paul\",\"address1\": \"123 paul lane\",\"name2\": \"George\",\"address2\": \"123 george lane\",\"name3\": \"Howie\",\"address3\": \"123 howie lane\"}";
var data = Newtonsoft.Json.Linq.JObject.Parse(json);
foreach (var pair in data)
{
yield return new KeyValuePair<string, string>(pair.Key, pair.Value.ToString());
}
}
An even better approach might be to use a JTokenReader, but I haven't used that before.
I believe the equivalent in System.Text.Json
of Newtonsoft.Json.Linq.JObject
is JsonDocument.
See Use JsonDocument for access to data.
Upvotes: 3