如何发出 GET 请求并将结果解析为列表

How to issue GET request and parse result to list

数据包含 place_id 和其他列:

place_id    name    city    address ..
133 place1  Laagri  Born 12 ..
161 place2  Mourdi  Karve 12  ..

数据有 5 种不同的格式。所有这些网址 return 相同的数据:

http://www.smartpost.ee/places.html
http://www.smartpost.ee/places.xml
http://www.smartpost.ee/places.csv
http://www.smartpost.ee/places.js
http://www.smartpost.ee/places.php

应该选择其中一个网址来获取数据。数据可能会更改,因此不应缓存。 如何发出 http GET 请求并创建两个元素列表:第一个元素是第一列的 place_id,第二个元素是连接的名称、城市和地址字段。类似于:

class DeliveryList {
   public string Id, Address;
  }

List<DeliveryList> res= GetAndParse("http://www.smartpost.ee/places.csv", 
    "place_id, name+\" \"+ city +\" \" + address" );

如何实现GetAndParse?是否应该将 http 请求保存到 sting 并使用 filehelpers 来解析它?表达式 "place_id, name+\" \"+ city +\" \" + address" 可以在代码中硬编码而不是作为参数传递。

使用 ASP.NET MVC4、.NET 4、C#。服务器中的 MVC4 控制器中的代码应 运行。

我建议您使用 XML 端点并对位置数组实施反序列化,如下所示:

public static class PlacesHelper
{
    private const string EndpointUrl = "http://www.smartpost.ee/places.xml";

    /// <summary> Load array of places </summary>
    public static async Task<Places> LoadPlacesAsync()
    {
        var xmlString = await HttpRequestHelper.DownloadStringAsync(EndpointUrl);
        return SerializationHelper.DeserializeXmlString<Places>(xmlString);
    }
}

public static class SerializationHelper
{
    /// <summary> Deserializes Xml string of type T. </summary>
    public static T DeserializeXmlString<T>(string xmlString)
    {
        T tempObject = default(T);

        using (var memoryStream = new MemoryStream(StringToUTF8ByteArray(xmlString)))
        {
            var xs = new XmlSerializer(typeof (T));
            var xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

            tempObject = (T) xs.Deserialize(memoryStream);
        }

        return tempObject;
    }

    /// <summary> Convert String to Array </summary>
    private static Byte[] StringToUTF8ByteArray(String xmlString)
    {
        return new UTF8Encoding().GetBytes(xmlString);
    }
}

public static class HttpRequestHelper
{
    /// <summary> Download String Async </summary>
    public static async Task<string> DownloadStringAsync(string uri)
    {
        var client = new WebClient();
        return await client.DownloadStringTaskAsync(uri);
    }
}

[Serializable]
[XmlRoot("places_info", Namespace = "")]
public class Places
{
    [XmlElement("place", typeof(Place), Form = XmlSchemaForm.Unqualified, IsNullable = false)]
    public Place[] Place { get; set; }
}

[Serializable]
public class Place
{
    [XmlElement("place_id")]
    public string Id { get; set; }

    [XmlElement("name")]
    public string Name { get; set; }

    [XmlElement("city")]
    public string City { get; set; }

    [XmlElement("address")]
    public string Address { get; set; }
}

用法:

var arrayOfPlaces = await PlacesHelper.LoadPlacesAsync();

因此,您将获得一组地点(id、姓名、城市、地址)。

更新:

对于 .NET Framework 4,Microsoft 发布了 Async Targeting Pack (Microsoft.Bcl.Async) through Nuget。因此,从 Nuget 安装 'Microsoft Async' 包,您将能够使用 async/await.

控制器操作的示例实现:

public class TestController : Controller
{
    public async Task<object> GetPlaces()
    {
        return Json(await PlacesHelper.LoadPlacesAsync(), JsonRequestBehavior.AllowGet);
    }
}

我选择XML格式解析数据,使用XmlSerializer。这是代码。

类代表我们的XML数据:代码自解释

[XmlRoot("places_info")]
public class PlacesInfo
{
    [XmlElement("place")]
    public Place[] Places { get; set; }
}

public class Place
{
    [XmlElement("place_id")]
    public string Id { get; set; }

    [XmlElement("name")]
    public string Name { get; set; }

    [XmlElement("city")]
    public string City { get; set; }

    [XmlElement("address")]
    public string Address { get; set; }
}

你的Deliveryclass:

public class Delivery
{
    public string Id { get; set; }
    public string Address { get; set; }

    public Delivery(string id, string address)
    {
        Id = id;
        Address = address;
    }
}

获取和解析数据的代码:

static void Main(string[] args)
{
    // Get XML string from web
    var client = new WebClient();

    // Set encoding for non-ASCII characters
    client.Encoding = Encoding.UTF8;

    string xml = client.DownloadString("http://www.smartpost.ee/places.xml");

    // Create a serializer
    var serializer = new XmlSerializer(typeof(PlacesInfo));

    // Variable to hold all XML data
    PlacesInfo info;

    // Deserialize XML string to object
    using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
    {
        info = (PlacesInfo) serializer.Deserialize(stream);
    }

    // Create delivery list
    var deliveryList = new List<Delivery>();

    // For each place
    foreach (var place in info.Places)
    {
        // Concatenate name, city, and address
        string address = string.Format("{0} {1} {2}", place.Name, place.City, place.Address);

        // Add new delivery
        var delivery = new Delivery(place.Id, address);
        deliveryList.Add(delivery);

        // Display to test
        Console.WriteLine(delivery.Id + " " + delivery.Address);
    }

    Console.ReadLine();
}

我小心翼翼地在代码中添加注释。如果您发现难以理解的内容,请随时告诉我。希望这有帮助:)