使用JSON在C#中进行API调用

时间:2016-11-29 16:04:49

标签: c# json

我有一个使用SmartyAddress的API调用,这是从API调用返回的结果:

[
  {
    "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"
    }
  }
]

现在我想使用JSON返回此结果,特别是分析组件,这是我尝试编写的代码,但它总是给我错误:无法反序列化当前的json对象进入'system.collections.generic.list 类型,以下是代码:

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; }
}

2 个答案:

答案 0 :(得分:5)

根据您的异常消息和您的代码,问题是您正在尝试将复杂对象从json反序列化为2个字符串数组,这2个显然不兼容。您应该使用与json中的匹配的复杂类型。要想先了解一下,你可以尝试http://json2csharp.com/,输入你的json,然后使用输出作为c#类结构的起点,然后匹配你的json。

该网站中当前json的输出是这个。

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; }
}

然后,您可以将json反序列化为此结构。

return JsonConvert.DeserializeObject<RootObject[]>(response);

答案 1 :(得分:1)

您的SmartyStreetsAddressLookup类不正确,并且与JSON数据不准确匹配。 metadataanalysis不应该是字符串数组,而是它们自己的对象(类),它们包含它们的属性。尝试将以下内容添加到项目中:

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; }
}

将您的SmartyStreetsAddressLookup课程更改为以下内容:

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; }
}