如何正确地提出一个 http web GET 请求

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

该类是一个对象,通过解析用户 ID 并发出请求就可以从表单访问它。

我已经尝试了许多例子,我已经看了谷歌,但不知道为什么我得到了所有的方式这条信息。

我是新在这种算法,如果任何人可以分享一本书或教程,显示如何做这种东西(解释每一步) ,我会很感激

510091 次浏览

服务器有时会压缩响应以节省带宽,当这种情况发生时,您需要在尝试读取响应之前解压缩响应。幸运的是。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);

走开

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

获取异步

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

职位
在希望使用其他 HTTP 方法(如 PUT、 DELETE、 ETC)的事件中包含参数 method

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


    


POST 异步
在希望使用其他 HTTP 方法(如 PUT、 DELETE、 ETC)的事件中包含参数 method

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

另一种方法是像这样使用‘ 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();
}
}
}

从堆栈溢出检查 HttpClient vs HttpWebRequest,从其他堆栈溢出检查 这个

更新于2020年6月22日: 不建议在“ using”块中使用 httpclient,因为它可能导致端口耗尽。

private static HttpClient client = null;
    

ContructorMethod()
{
if(client == null)
{
HttpClientHandler handler = new HttpClientHandler()
{
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
client = new HttpClient(handler);
}
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);
}

如果使用.Net Core 2.1 + ,可以考虑使用 IHttpClientFactory并在启动代码中像这样注入。

 var timeout = Policy.TimeoutAsync<HttpResponseMessage>(
TimeSpan.FromSeconds(60));


services.AddHttpClient<XApiClient>().ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
{
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
}).AddPolicyHandler(request => timeout);
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();
}
}

用最简单的方式表达我的意见

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

或者

 var bytes = web.DownloadData(url);

添加到已经给出的回应,这是一个完整的例子中的 JSON PlaceHolder站点。

using System;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;


namespace Publish
{
class Program
{
static async Task Main(string[] args)
{
            

// Get Reqeust
HttpClient req = new HttpClient();
var content = await req.GetAsync("https://jsonplaceholder.typicode.com/users");
Console.WriteLine(await content.Content.ReadAsStringAsync());


// Post Request
Post p = new Post("Some title", "Some body", "1");
HttpContent payload = new StringContent(JsonConvert.SerializeObject(p));
content = await req.PostAsync("https://jsonplaceholder.typicode.com/posts", payload);
Console.WriteLine("--------------------------");
Console.WriteLine(content.StatusCode);
Console.WriteLine(await content.Content.ReadAsStringAsync());
}
}


public struct Post {
public string Title {get; set;}
public string Body {get;set;}
public string UserID {get; set;}


public Post(string Title, string Body, string UserID){
this.Title = Title;
this.Body = Body;
this.UserID = UserID;
}
}
}