I'm trying to call a web API (JSON/Csharp Console application) I did the same steps in the dotnet : https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/console-webapiclient However, when I'm trying to get only the property "NAME1", an error came up : The JSON value could not be converted to System.Collections.Generic.List. I could get all the json information but when Deserializing the result for getting only particular data such as NAME1 it doesn't work.
public partial class Result
{
public List<GAZETTEER_ENTRY> GAZETTEER_ENTRY { get; set; }
}
public partial class GAZETTEER_ENTRY
{
public string ID { get; set; }
public string NAME1 { get; set; }
}
class Program
{
private static readonly HttpClient client = new HttpClient();
static async Task Main(string[] args)
{
await RunAsync();
}
private static async Task RunAsync()
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("key", "xxxxxx");
var streamTask = client.GetStreamAsync("https://api.os.uk/search/names/v1/find?query=coventry&fq=LOCAL_TYPE:Hospital");
var data = await JsonSerializer.DeserializeAsync<List<GAZETTEER_ENTRY>>(await streamTask);
foreach (var item in data)
{
Console.WriteLine(item.NAME1);
}
This is the JSON data:
"header" : {
"uri" : "https://api.os.uk/search/names/v1/find?query=coventry",
"query" : "coventry",
"format" : "JSON",
"maxresults" : 100,
"offset" : 0,
"totalresults" : 4134
},
"results" : [ {
"GAZETTEER_ENTRY" : {
"ID" : "osgb4000000074568994",
"NAMES_URI" : "http://data.ordnancesurvey.co.uk/id/4000000074568994",
"NAME1" : "Coventry",
"TYPE" : "populatedPlace",
"LOCAL_TYPE" : "City",
"COUNTRY" : "England",
}
}, {
"GAZETTEER_ENTRY" : {
"ID" : "osgb4000000019401618",
"NAMES_URI" : "http://data.ordnancesurvey.co.uk/id/4000000019401618",
"NAME1" : "Coventry Street",
"TYPE" : "transportNetwork",
"LOCAL_TYPE" : "Named Road",
"COUNTRY" : "England",
}
}, {
"GAZETTEER_ENTRY" : {
"ID" : "osgb4000000073321650",
"NAMES_URI" : "http://data.ordnancesurvey.co.uk/id/4000000073321650",
"NAME1" : "Coventry",
"TYPE" : "transportNetwork",
"LOCAL_TYPE" : "Railway Station",
"COUNTRY" : "England",
}
CodePudding user response:
Your response classes should be like
public class SearchResult
{
public Header header { get; set; }
public Result[] results { get; set; }
}
public class Header
{
public string uri { get; set; }
public string query { get; set; }
public string format { get; set; }
public int maxresults { get; set; }
public int offset { get; set; }
public int totalresults { get; set; }
}
public class Result
{
public GAZETTEER_ENTRY GAZETTEER_ENTRY { get; set; }
}
public class GAZETTEER_ENTRY
{
public string ID { get; set; }
public string NAMES_URI { get; set; }
public string NAME1 { get; set; }
public string TYPE { get; set; }
public string LOCAL_TYPE { get; set; }
public string COUNTRY { get; set; }
}
and the deserialize should be
var data = await JsonSerializer.DeserializeAsync<SearchResult>(await streamTask);
and access NAME1 of nth result
data.results[0].GAZETTEER_ENTRY.NAME1
if you find difficulty in comparing classes and json response, You can simply copy the json response and goto VS -> edit-> paste special -> paste json as classes. VS will auto generate classes for you.
CodePudding user response:
Try deserialing the json using this RootObject model:
public class RootObject
{
public ResultObject[] results { get; set; }
}
public class ResultObject
{
public GazetteerEntryObject GAZETTEER_ENTRY { get; set; }
}
public class GazetteerEntryObject
{
public string NAME1 { get; set; }
}
Do it this way
var data = await JsonSerializer.DeserializeAsync<RootObject>(await streamTask);
The to retrieve the names, do it like this:
var names = data.results.Select(x => x.GAZETTEER_ENTRY.NAME1);