Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

API Call in C# using JSON

Tags:

json

c#

I have an API call using SmartyAddress, here is the result returned from the API call:

[
  {
    "input_index": 0,
    "candidate_index": 0,
    "delivery_line_1": "xx",
    "last_line": "xx",
    "delivery_point_barcode": "xx",
    "components": {
      "primary_number": "xx",
      "street_name": "xx",
      "street_suffix": "xx",
      "city_name": "xx",
      "state_abbreviation": "xx",
      "zipcode": "xx",
      "plus4_code": "xx",
      "delivery_point": "xx",
      "delivery_point_check_digit": "xx"
    },
    "metadata": {
      "record_type": "S",
      "zip_type": "Standard",
      "county_fips": "36047",
      "county_name": "Kings",
      "carrier_route": "C009",
      "congressional_district": "11",
      "rdi": "Residential",
      "elot_sequence": "0070",
      "elot_sort": "A",
      "latitude": 40.6223,
      "longitude": -74.00717,
      "precision": "Zip9",
      "time_zone": "Eastern",
      "utc_offset": -5,
      "dst": true
    },
    "analysis": {
      "dpv_match_code": "Y",
      "dpv_footnotes": "AABB",
      "dpv_cmra": "N",
      "dpv_vacant": "N",
      "active": "Y"
    }
  }
]

Now I would like to use JSON to return this result especially the analysis component, and here is the code I tried to write, but it always gives me the error:cannot deserialize the current json object into type 'system.collections.generic.list and the following is the code:

public void Main() 
{
    try
    {
        var results = Client.Lookup(Dts.Variables["User::authID"].Value.ToString(), Dts.Variables["User::ServiceAddress"].Value.ToString(), Dts.Variables["User::ServiceCity"].Value.ToString(), Dts.Variables["User::ServiceState"].Value.ToString(), Dts.Variables["User::ServiceZipCode"].Value.ToString());

        if (results == null)
        {
            throw new Exception("Failed to get DPV for ServiceAddress");
        }
        else
        {
            var DPV = results.analysis;
            Dts.Variables["User::DPV"].Value = DPV;
        }
        }
    }
    catch (Exception ex)
    {                             
        Dts.Variables["User::DPV"].Value = "N";            
        throw ex;
    }

    Dts.TaskResult = (int)ScriptResults.Success;
}

public class Client
{
    public static SmartyStreetsAddressLookup[] Lookup(string authId = null, string street = null, string city = null, string state = null, string zip = null)
    {
        try
        {
            using (WebClient web = new WebClient())
            {
                JsonSerializer serial = new JsonSerializer();
                string response = web.DownloadString(new Uri(String.Format(@"https://us-street.api.smartystreets.com/street-address?auth-id={0}&street={1}&city={2}&state={3}&zipcode={4}", authId, street, city, state, zip)));
                return JsonConvert.DeserializeObject<SmartyStreetsAddressLookup[]>(response);
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}

public class SmartyStreetsAddressLookup
{
    public String[] metadata { get; set; }
    public String[] analysis { get; set; }
}
like image 500
LONG Avatar asked Nov 29 '16 16:11

LONG


2 Answers

Based on your exception message and your code the problem is that you are trying to deserialize a complex object from json into 2 string arrays, those 2 are clearly not compatible. You should be using a complex type that matches what you have in your json. To get a head start on this you can try http://json2csharp.com/, enter your json, and then use the output as a starting point for your c# class structure that then matches your json.

The output of your current json in that site is this.

public class Components
{
    public string primary_number { get; set; }
    public string street_name { get; set; }
    public string street_suffix { get; set; }
    public string city_name { get; set; }
    public string state_abbreviation { get; set; }
    public string zipcode { get; set; }
    public string plus4_code { get; set; }
    public string delivery_point { get; set; }
    public string delivery_point_check_digit { get; set; }
}

public class Metadata
{
    public string record_type { get; set; }
    public string zip_type { get; set; }
    public string county_fips { get; set; }
    public string county_name { get; set; }
    public string carrier_route { get; set; }
    public string congressional_district { get; set; }
    public string rdi { get; set; }
    public string elot_sequence { get; set; }
    public string elot_sort { get; set; }
    public double latitude { get; set; }
    public double longitude { get; set; }
    public string precision { get; set; }
    public string time_zone { get; set; }
    public int utc_offset { get; set; }
    public bool dst { get; set; }
}

public class Analysis
{
    public string dpv_match_code { get; set; }
    public string dpv_footnotes { get; set; }
    public string dpv_cmra { get; set; }
    public string dpv_vacant { get; set; }
    public string active { get; set; }
}

public class RootObject
{
    public int input_index { get; set; }
    public int candidate_index { get; set; }
    public string delivery_line_1 { get; set; }
    public string last_line { get; set; }
    public string delivery_point_barcode { get; set; }
    public Components components { get; set; }
    public Metadata metadata { get; set; }
    public Analysis analysis { get; set; }
}

You can then deserialize your json into this structure.

return JsonConvert.DeserializeObject<RootObject[]>(response);
like image 195
Igor Avatar answered Oct 04 '22 23:10

Igor


Your SmartyStreetsAddressLookup class is incorrect, and does not accurately match the JSON data. metadata and analysis should not be string arrays, but rather their own objects (classes) with the properties that they contain. Try adding the following to your project:

public class Metadata
{
    public string record_type { get; set; }
    public string zip_type { get; set; }
    public string county_fips { get; set; }
    public string county_name { get; set; }
    public string carrier_route { get; set; }
    public string congressional_district { get; set; }
    public string rdi { get; set; }
    public string elot_sequence { get; set; }
    public string elot_sort { get; set; }
    public double latitude { get; set; }
    public double longitude { get; set; }
    public string precision { get; set; }
    public string time_zone { get; set; }
    public int utc_offset { get; set; }
    public bool dst { get; set; }
}

public class Analysis
{
    public string dpv_match_code { get; set; }
    public string dpv_footnotes { get; set; }
    public string dpv_cmra { get; set; }
    public string dpv_vacant { get; set; }
    public string active { get; set; }
}

public class Components
{
    public string primary_number { get; set; }
    public string street_name { get; set; }
    public string street_suffix { get; set; }
    public string city_name { get; set; }
    public string state_abbreviation { get; set; }
    public string zipcode { get; set; }
    public string plus4_code { get; set; }
    public string delivery_point { get; set; }
    public string delivery_point_check_digit { get; set; }
}

And change your SmartyStreetsAddressLookup class to the following:

public class SmartyStreetsAddressLookup
{
    public int input_index { get; set; }
    public int candidate_index { get; set; }
    public string delivery_line_1 { get; set; }
    public string last_line { get; set; }
    public string delivery_point_barcode { get; set; }
    public Components components { get; set; }
    public Metadata metadata { get; set; }
    public Analysis analysis { get; set; }
}
like image 32
Bryan Avatar answered Oct 05 '22 00:10

Bryan