I'm trying to convert a data from a nested JSon file to C# Model, and I get this error :
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[convert_json_to_model.Fields]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'nhits', line 1, position 9.
Here is some data
{
"nhits":17933,
"parameters":{
"dataset":[
"osm-fr-bars@babel"
],
"rows":3,
"start":0,
"format":"json",
"timezone":"UTC"
},
"records":[
{
"datasetid":"osm-fr-bars@babel",
"recordid":"d95394fd7d34aa34aa9b236661bce9cda534a8ab",
"fields":{
"other_tags":"{\"cuisine\": \"tapas\", \"ref:FR:CRTA\": \"RESAQU047V506W6V\",
\"capacity\": \"14\", \"description\": \"Tous les jours \u00e0 partir de 7h\",
\"source\": \"BDOrtho IGN; Cadastre M\u00e0J 2015; Sirtaqui\", \"outdoor_seating\":
\"yes\", \"source:ref:FR:CRTA\": \"Sirtaqui\"}",
"name":"Au boin coin",
"geo_point_2d":[
44.0549704,
0.2603921
],
"phone":" 33 5 53 65 67 45"
},
"geometry":{
"type":"Point",
"coordinates":[
0.2603921,
44.0549704
]
}
Here is the link of my Json file to see all fields : https://data.opendatasoft.com/api/records/1.0/search/?dataset=osm-fr-bars@babel&rows=30
Here is my model after using the tool JSON to C#
public class Fields
{
[JsonProperty("other_tags")]
public string OtherTags { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("geo_point_2d")]
public List<double> GeoPoint2d { get; set; }
[JsonProperty("phone")]
public string Phone { get; set; }
}
public class Geometry
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("coordinates")]
public List<double> Coordinates { get; set; }
}
public class Record
{
[JsonProperty("datasetid")]
public string Datasetid { get; set; }
[JsonProperty("recordid")]
public string Recordid { get; set; }
[JsonProperty("fields")]
public Fields Fields { get; set; }
[JsonProperty("geometry")]
public Geometry Geometry { get; set; }
}
public class Root
{
[JsonProperty("records")]
public List<Record> Records { get; set; }
}
Here is the method to deserialize
static async Task Main(string[] args)
{
string url = "https://data.opendatasoft.com/api/records/1.0/search/?dataset=osm-fr-bars@babel&rows=30";
HttpClient httpClient = new HttpClient();
try
{
var httpResponseMessage = await httpClient.GetAsync(url);
string jsonResponse = await httpResponseMessage.Content.ReadAsStringAsync();
List<Fields> myBars = JsonConvert.DeserializeObject<List<Fields>>(jsonResponse);
foreach (var bar in myBars)
{
Console.WriteLine($"{bar.Name}");
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
CodePudding user response:
In the main, the HTTP response is deserialized to the type List<Fields>
. But the JSON rather corresponds the type Root
. Try :
//List<Fields> myBars = JsonConvert.DeserializeObject<List<Fields>>(jsonResponse);
Root myBars = JsonConvert.DeserializeObject<Root>(jsonResponse);
CodePudding user response:
Please organise your model well.
Fields myBars = JsonConvert.DeserializeObject<Fields>(jsonResponse);
or
Root myBars = JsonConvert.DeserializeObject<Root>(jsonResponse);
public class Root
{
[JsonProperty("records")]
public List<Record> Records { get; set; }
}
public class Record
{
[JsonProperty("datasetid")]
public string Datasetid { get; set; }
[JsonProperty("recordid")]
public string Recordid { get; set; }
[JsonProperty("fields")]
public Fields Fields { get; set; }
[JsonProperty("geometry")]
public Geometry Geometry { get; set; }
}
public class Fields
{
[JsonProperty("other_tags")]
public string OtherTags { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("geo_point_2d")]
public List<double> GeoPoint2d { get; set; }
[JsonProperty("phone")]
public string Phone { get; set; }
}
public class Geometry
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("coordinates")]
public List<double> Coordinates { get; set; }
}
CodePudding user response:
fix your class Root and add a missed Parameters class
Root data =JsonConvert.DeserializeObject<Root>(jsonResponse);
List<Fields> myBars = data.Records.Select(f=> f.Fields).ToList();
foreach (var bar in myBars)
{
Console.WriteLine($"{bar.Name}");
}
public partial class Root
{
[JsonProperty("nhits")]
public long Nhits { get; set; }
[JsonProperty("parameters")]
public Parameters Parameters { get; set; }
[JsonProperty("records")]
public List<Record> Records { get; set; }
}
public partial class Parameters
{
[JsonProperty("dataset")]
public List<string> Dataset { get; set; }
[JsonProperty("rows")]
public long Rows { get; set; }
[JsonProperty("start")]
public long Start { get; set; }
[JsonProperty("format")]
public string Format { get; set; }
[JsonProperty("timezone")]
public string Timezone { get; set; }
}