Home > database >  Calling a Web API to get particular information using DeserializineAsync (JSON/ C#)
Calling a Web API to get particular information using DeserializineAsync (JSON/ C#)

Time:10-29

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);
  • Related