C#如何正确制作http web GET请求

Osc*_*yes 97 .net c# httpwebrequest

我仍然是c#的新手,我正在尝试为这个页面创建一个应用程序,告诉我何时收到通知(回答,评论等等).但是现在我只是想简单地调用api来获取用户的数据.

我正在使用Visual Studio express 2012来构建C#应用程序,其中(现在)您输入了您的用户ID,因此应用程序将使用用户ID发出请求并显示此用户ID的统计信息.

这是我正在尝试发出请求的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Request library
using System.Net;
using System.IO;

namespace TestApplication
{
    class Connect
    {
        public string id;
        public string type;

        protected string api = "https://api.stackexchange.com/2.2/";
        protected string options = "?order=desc&sort=name&site=stackoverflow";

        public string request()
        {
            string totalUrl = this.join(id);

            return this.HttpGet(totalUrl);
        }

        protected string join(string s)
        {
            return api + type + "/" + s + options;
        }

        protected string get(string url)
        {
            try
            {
                string rt;

                WebRequest request = WebRequest.Create(url);

                WebResponse response = request.GetResponse();

                Stream dataStream = response.GetResponseStream();

                StreamReader reader = new StreamReader(dataStream);

                rt = reader.ReadToEnd();

                Console.WriteLine(rt);

                reader.Close();
                response.Close();

                return rt;
            }

            catch(Exception ex)
            {
                return "Error: " + ex.Message;
            }
        }
        public string HttpGet(string URI)
        {
            WebClient client = new WebClient();

            // Add a user agent header in case the 
            // requested URI contains a query.

            client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");

            Stream data = client.OpenRead(URI);
            StreamReader reader = new StreamReader(data);
            string s = reader.ReadToEnd();
            data.Close();
            reader.Close();

            return s;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

该类是一个对象,只需将其解析为用户ID并发出请求即可从表单中访问它.

我已经尝试了很多我在google上看过的例子,但不知道为什么我会在这个消息" "的所有方式.

我是这种算法的新手,如果有人可以分享一本书或教程,说明如何做这种事情(解释每一步),我将不胜感激

Ayd*_*din 212

服务器有时会压缩其响应以节省带宽,当发生这种情况时,您需要在尝试读取之前解压缩响应.幸运的是,.NET框架可以自动执行此操作,但是,我们必须打开设置.

这是一个如何实现这一目标的例子.

string html = string.Empty;
string url = @"https://api.stackexchange.com/2.2/answers?order=desc&sort=activity&site=stackoverflow";

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AutomaticDecompression = DecompressionMethods.GZip;

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
    html = reader.ReadToEnd();
}

Console.WriteLine(html);
Run Code Online (Sandbox Code Playgroud)

编辑23/11/17

更新为使用异步同时为GET请求和POST抛出示例


得到

public string Get(string uri)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

    using(HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    using(Stream stream = response.GetResponseStream())
    using(StreamReader reader = new StreamReader(stream))
    {
        return reader.ReadToEnd();
    }
}
Run Code Online (Sandbox Code Playgroud)

GET异步

public async Task<string> GetAsync(string uri)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

    using(HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
    using(Stream stream = response.GetResponseStream())
    using(StreamReader reader = new StreamReader(stream))
    {
        return await reader.ReadToEndAsync();
    }
}
Run Code Online (Sandbox Code Playgroud)

POST
包含method您希望使用其他HTTP方法(如PUT,DELETE,ETC)的参数

public string Post(string uri, string data, string contentType, string method = "POST")
{
    byte[] dataBytes = Encoding.UTF8.GetBytes(data);

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
    request.ContentLength = dataBytes.Length;
    request.ContentType = contentType;
    request.Method = method;

    using(Stream requestBody = request.GetRequestStream())
    {
        requestBody.Write(dataBytes, 0, dataBytes.Length);
    }

    using(HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    using(Stream stream = response.GetResponseStream())
    using(StreamReader reader = new StreamReader(stream))
    {
        return reader.ReadToEnd();
    }
}
Run Code Online (Sandbox Code Playgroud)

POST async
包含method您希望使用其他HTTP方法(如PUT,DELETE,ETC)的参数

public async Task<string> PostAsync(string uri, string data, string contentType, string method = "POST")
{
    byte[] dataBytes = Encoding.UTF8.GetBytes(data);

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
    request.ContentLength = dataBytes.Length;
    request.ContentType = contentType;
    request.Method = method;

    using(Stream requestBody = request.GetRequestStream())
    {
        await requestBody.WriteAsync(dataBytes, 0, dataBytes.Length);
    }

    using(HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
    using(Stream stream = response.GetResponseStream())
    using(StreamReader reader = new StreamReader(stream))
    {
        return await reader.ReadToEndAsync();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你可能想要展示一个如何解析`html`字符串`+ 1`以获得干净代码的例子. (4认同)
  • @ahmadmolaie添加了它们,以及如何执行POST请求 (2认同)

小智 33

另一种方法是像这样使用'HttpClient':

using System;
using System.Net;
using System.Net.Http;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Making API Call...");
            using (var client = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }))
            {
                client.BaseAddress = new Uri("https://api.stackexchange.com/2.2/");
                HttpResponseMessage response = client.GetAsync("answers?order=desc&sort=activity&site=stackoverflow").Result;
                response.EnsureSuccessStatusCode();
                string result = response.Content.ReadAsStringAsync().Result;
                Console.WriteLine("Result: " + result);
            }
            Console.ReadLine();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

HttpClient与HttpWebRequest

  • 根据https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/,切勿将HttpClient包装在using语句中。 (4认同)
  • @sfors永不言败。看代码。HttpClient实例在该程序的生命周期内仅被使用一次,并在程序退出之前被处置。那是完全正确和适当的。 (2认同)

小智 9

我的意见最简单的方式

  var web = new WebClient();
  var url = $"{hostname}/LoadDataSync?systemID={systemId}";
  var responseString = web.DownloadString(url);
Run Code Online (Sandbox Code Playgroud)

或者

 var bytes = web.DownloadData(url);
Run Code Online (Sandbox Code Playgroud)


小智 5

var request = (HttpWebRequest)WebRequest.Create("sendrequesturl");
var response = (HttpWebResponse)request.GetResponse();
string responseString;
using (var stream = response.GetResponseStream())
{
    using (var reader = new StreamReader(stream))
    {
        responseString = reader.ReadToEnd();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 代码不会释放对象;可能是内存泄漏。需要使用语句。 (6认同)