使用WebRequest在C#中使用Yahoo PlaceFinder JSON

时间:2012-06-24 11:21:05

标签: c# json httpwebrequest yahoo jsonserializer

我以为我会在这里发布这个问题而不是一个问题,但是在没有能够在StackOverflow上找到答案之后与社区分享我写的一些代码。如果有人想看看代码并改进它,那将是很好的,但不是必需的。我省略了一些代码(try-catch块和错误处理),使它更容易使用概念和代码。

2 个答案:

答案 0 :(得分:0)

所以,让我们从我需要解决的问题开始吧。我希望能够允许某人输入城市,州,邮政编码组合的部分或全部,并使用Yahoo's PlaceFinder API确切地知道它的位置。没什么好看的,只是解决城市和城市的简单方法。从邮政编码说明,反之亦然。

此过程涉及:

  1. 接收输入(城市/州/邮政编码)服务器端
  2. 使用适当的参数构建URL(我希望以JSON格式接收响应)
  3. 向PlaceFinder服务发出HTTP GET请求。
  4. 以一种在C#中为我提供对象模型的方式来使用JSON响应,以便轻松使用响应数据。
  5. 让我们从您要导入的命名空间开始:

    using System.Net; // for HttpWebRequest
    using System.Text; // for utf8 encoding
    using System.Web.Script.Serialization; // for json parsing
    using System.IO; // for datastream
    

    接下来,让我们看看构建请求:

    string parameters = String.Empty;
    UTF8Encoding utf8 = new UTF8Encoding(); // yahoo docs state utf-8 encoding
    string unparsedLocation = "Beverly Hills, CA 90210"; // contrived example
    
    parameters += "line2=" + Url.Encode(unparsedLocation); // yahoo docs say to url encode
    parameters += "&flags=J"; // J = want the response formatted in json
    parameters += "&appid=[your-app-id-here]"; // using your appID obtained from Yahoo
    parameters = utf8.GetString(utf8.GetBytes(parameters));
    WebRequest request = WebRequest.Create(@"http://where.yahooapis.com/geocode?" + parameters);
    request.Method = "GET";
    

    接下来,我们希望获得响应并将其放入一个易于使用的对象模型中:

    WebResponse response = request.GetResponse();
    // Check the status. If it's not OK then don't bother with trying to parse the result
    if (((HttpWebResponse)response).StatusCode == HttpStatusCode.OK)
    {
        // Get the stream containing content returned by the server.
        Stream dataStream = response.GetResponseStream();
        // Open the stream using a StreamReader.
        StreamReader reader = new StreamReader(dataStream);
        // Read the content.
        string responseFromServer = reader.ReadToEnd();
    
        JavaScriptSerializer jss = new JavaScriptSerializer();
        YahooResponse yr = jss.Deserialize<YahooResponse>(responseFromServer);
    
        // You may not want such strict checking; if not, remove the "NO ERROR" check
        if (yr.ResultSet.Error == 0 && yr.ResultSet.ErrorMessage.ToUpper() == "NO ERROR" && yr.ResultSet.Found > 0)
        {
            // inside here is where you can do whatever you need to.
            // ex. 1 - get the first result
            Result result = yr.ResultSet.results[0];
    
            // ex. 2 - loop through results
            foreach (Result r in yr.ResultSet.results)
            {
                // add values to a List<T> or something useful
            }
        }
    }
    
    // always do this as a matter of good practice
    response.Close();
    

    但是等等,最后一件重要的遗失了。什么是“YahooResponse”对象?类定义是什么样的?以下是我提出的建议:

    namespace PlaceFinder
    {
        public class YahooResponse
        {
            public ResultSet ResultSet { get; set; }
        }
    
        public class ResultSet
        {
            public string version { get; set; }
            public int Error { get; set; }
            public string ErrorMessage { get; set; }
            public string Locale { get; set; }
            public int Quality { get; set; }
            public int Found { get; set; }
            public Result[] results { get; set; }
        }
    
        public class Result
        {
            public int quality { get; set; }
            public string latitude { get; set; }
            public string longitude { get; set; }
            public string offsetlat { get; set; }
            public string offsetlon { get; set; }
            public int radius { get; set; }
            public string name { get; set; }
            public string line1 { get; set; }
            public string line2 { get; set; }
            public string line3 { get; set; }
            public string line4 { get; set; }
            public string house { get; set; }
            public string street { get; set; }
            public string xstreet { get; set; }
            public string unittype { get; set; }
            public string unit { get; set; }
            public string postal { get; set; }
            public string neighborhood { get; set; }
            public string city { get; set; }
            public string county { get; set; }
            public string state { get; set; }
            public string country { get; set; }
            public string countrycode { get; set; }
            public string statecode { get; set; }
            public string countycode { get; set; }
            public string uzip { get; set; }
            public string hash { get; set; }
            public long woeid { get; set; }
            public int woetype { get; set; }
        }
    }
    

    在此处详细了解PlaceFinder服务:http://developer.yahoo.com/geo/placefinder/guide/

答案 1 :(得分:0)

幸运的是有人在GIT上为此写了一个包装器。这是LINK:https://github.com/danludwig/NGeo。它也可以通过NuGet获得。对我来说非常方便!