C# 如何发出GET请求并将结果解析到列表

C# 如何发出GET请求并将结果解析到列表,c#,asp.net,asp.net-mvc,parsing,filehelpers,C#,Asp.net,Asp.net Mvc,Parsing,Filehelpers,数据包含place_id和其他列: place_id name city address .. 133 place1 Laagri Born 12 .. 161 place2 Mourdi Karve 12 .. 数据有5种不同的格式。所有这些URL返回相同的数据: http://www.smartpost.ee/places.html http://www.smartpost.ee/places.xml http://www.smartpost.ee/places

数据包含place_id和其他列:

place_id    name    city    address ..
133 place1  Laagri  Born 12 ..
161 place2  Mourdi  Karve 12  ..
数据有5种不同的格式。所有这些URL返回相同的数据:

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
应选择其中一个URL以获取数据。数据可能会更改,因此不应缓存。 如何发出http GET requet并创建两个元素列表:第一个元素是第一列的place_id,第二个元素是连接的name、city和address字段。比如:

class DeliveryList {
   public string Id, Address;
  }

List<DeliveryList> res= GetAndParse("http://www.smartpost.ee/places.csv", 
    "place_id, name+\" \"+ city +\" \" + address" );
类交付列表{
公共字符串Id、地址;
}
List res=GetAndParse(“http://www.smartpost.ee/places.csv", 
“地点id,姓名+\”\“+”城市+\“\”+地址”);
如何实现GetAndParse?http请求应该保存到sting和用于解析它的FileHelper吗?表达式
“place\u 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; }
}
因此,您将获得一个位置数组(id、名称、城市、地址)

更新:

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();
}
对于.NET Framework 4,Microsoft通过发布了。因此,从Nuget安装软件包“MicrosoftAsync”,您将能够使用Async/await

控制器操作的示例实现:

public class TestController : Controller
{
    public async Task<object> GetPlaces()
    {
        return Json(await PlacesHelper.LoadPlacesAsync(), JsonRequestBehavior.AllowGet);
    }
}
公共类TestController:Controller
{
公共异步任务GetPlaces()
{
返回Json(wait 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; }
}
您的
交付
课程:

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();
}
获取和分析数据的代码:

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();
}
static void Main(字符串[]args)
{
//从web获取XML字符串
var client=new WebClient();
//设置非ASCII字符的编码
client.Encoding=Encoding.UTF8;
string xml=client.DownloadString(“http://www.smartpost.ee/places.xml");
//创建序列化程序
var serializer=新的XmlSerializer(typeof(PlacesInfo));
//变量来保存所有XML数据
地点信息;
//将XML字符串反序列化为对象
使用(var stream=newmemoryStream(Encoding.UTF8.GetBytes(xml)))
{
info=(PlacesInfo)序列化程序。反序列化(流);
}
//创建交货清单
var deliveryList=新列表();
//每个地方
foreach(信息位置中的变量位置)
{
//连接名称、城市和地址
string address=string.Format(“{0}{1}{2}”,place.Name,place.City,place.address);
//添加新交付
var交货=新交货(地点Id、地址);
deliveryList.Add(delivery);
//显示测试
Console.WriteLine(delivery.Id+“”+delivery.Address);
}
Console.ReadLine();
}

我仔细地在代码中添加了注释。如果你发现一些难以理解的事情,请随时告诉我。希望获得以下帮助:)

返回数据的格式是什么?您可以在浏览器中打开这些链接以查看数据。是以逗号分隔的。是否要分析所有格式,或者只分析一种格式就足够了?一种格式就足够了。可以从这些格式中选择最合适的格式。为什么使用asunc?这是单线程和正常的同步方法可以使用,不是吗?数据在平面表格中。也许csv格式的解析更简单,应该使用csv格式?您编写了“代码应该在服务器的MVC4控制器中运行”。对于长时间运行的任务(如从远程服务器加载xml),在控制器中使用asyc操作方法是一种更好的方法。您可以在此处阅读更多详细信息,行
等待HttpRequestHelper。DownloadStringAsync(EndpointUrl)
导致编译错误
“Task”不包含“GetAwaiter”的定义,并且找不到接受“Task”类型的第一个参数的扩展方法“GetAwaiter”
。问题指出目标框架是.NET4。如何解决这个问题?Async/Await是.Net Framework 4.5的一项功能。您可以升级您的解决方案以使用此版本吗?或者我应该帮助您实现.Net Framework 4的异步代码吗?代码应该在Windows 2003 server中运行。如果升级到.NET 4.5,如何支持它?如果无法升级,那么是的,如何实现.NET 4?DownloadAsTringAsync还错误地返回非ascii字符。如何将正确的unicode字符转换为字符串?一个Triet应答在Net4中工作,这应该使用还是可以在.NET4MVC4控制器中使用异步的东西?由
DownloadString
返回的字符串中,非ascii字符在中显示为两个stange字符。如何正确获取非ascii字符,如单个unicode字符?如果直接在浏览器中打开xml链接,则它们是正确的。您的答案解决了问题。为什么不像Yuriy A中那样使用async来提高MVC性能呢?我将您的答案标记为answer,因为它提供了client.Encoding设置。因为您问题的重点是获取和解析数据,而不是异步任务。我保持代码简单易懂,然后您可以根据需要对其进行优化:)谢谢,非常好的答案,尤其是编码设置。然而,Yuriy A.也包含MVC4和MVC4.5的异步用法。看起来这是合理的,增加了价值,所以我把它标记为答案。对不起。我对你的答案投了赞成票,没关系。我同意你的看法。Yuriy A在处理异步任务方面做得很好。如果你想知道他为什么那样做,看看这个很棒的。乐意帮忙:)