相关文章推荐
年轻有为的啄木鸟  ·  博士申请 | ...·  1 年前    · 

[译]C# HttpClient使用 .net core

原文链接: C# HttpClient (ZetCode)


最后修改于2021年3月13日


C# HttpClient教程展示了如何在C#中用HttpClient创建HTTP请求。在例子中,我们创建了简单的GET和POST请求。


超文本传输协议(HTTP)是一个分布式、协作式、超媒体信息系统的应用协议。HTTP是万维网的数据通信的基础。


HttpClient是一个基类,用于发送HTTP请求和接收由URI标识的资源的HTTP响应。


C# HttpClient状态码

HTTP响应状态码表示一个特定的HTTP请求是否已经成功完成。响应被分组为五个类别。


信息性响应(100-199)

成功响应(200-299)

重定向(300-399)

客户端错误(400-499)

服务器错误(500-599)


Program.cs

using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace HttpClientStatus
    class Program
        static async Task Main(string[] args)
            using var client = new HttpClient();
            var result = await client.GetAsync("http://webcode.me");
            Console.WriteLine(result.StatusCode);

这个例子为一个小网站创建了一个GET请求。我们得到该请求的状态代码。

using var client = new HttpClient();

一个新的HttpClient被创建。


var result = await client.GetAsync("http://webcode.me");

GetAsync方法作为一个异步操作向指定的Uri发送一个GET请求。await操作者会暂停对包围的异步方法的评估,直到异步操作完成。当异步操作完成时,await操作符返回操作的结果(如果有的话)。

$ dotnet run
OK

我们得到200 OK状态代码;网站已经启动。


C# HttpClient GET请求

GET方法请求指定资源的表示。

using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace HttpClientEx
    class Program
        static async Task Main(string[] args)
            using var client = new HttpClient();
            var content = await client.GetStringAsync("http://webcode.me");
            Console.WriteLine(content);

这个例子向 webcode.me 网站发出一个GET请求。它输出主页的简单HTML代码。

var content = await client.GetStringAsync("http://webcode.me");

GetStringAsync向指定的Uri发送一个GET请求,并以异步操作的方式返回响应体。

$ dotnet run
<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My html page</title>
</head>
        Today is a beautiful day. We go swimming and fishing.
         Hello there. How are you?
</body>
</html>

C# HttpClient HEAD请求

HTTP HEAD方法要求返回头信息,如果用HTTP GET方法请求指定的资源,就会返回头信息。

using System;
using System.Net.Http;
var url = "http://webcode.me";
using var client = new HttpClient();
var result = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url));
Console.WriteLine(result);

这个例子发出一个HEAD请求。

$ # dotnet run
StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, 
Content: System.Net.Http.HttpConnectionResponseContent, Headers:
  Server: nginx/1.6.2
  Date: Tue, 12 Jan 2021 12:01:07 GMT
  Connection: keep-alive
  ETag: "5d32ffc5-15c"
  Accept-Ranges: bytes
  Content-Type: text/html
  Content-Length: 348
  Last-Modified: Sat, 20 Jul 2019 11:49:25 GMT
}

这些是响应的头字段。


C# HttpClient 多个GET请求

在下面的例子中,我们产生了多个异步GET请求。

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
var urls = new string[] {"http://webcode.me", "http://example.com",
    "http://httpbin.org"};
using var client = new HttpClient();
var tasks = new List<Task<string>>();
foreach (var url in urls)
    tasks.Add(client.GetStringAsync(url));
Task.WaitAll(tasks.ToArray());
var data = new List<string> { await tasks[0], await tasks[1], await tasks[2] };
var rx = new Regex(@"<title>\s*(.+?)\s*</title>", RegexOptions.Compiled);
foreach (var content in data)
    var matches = rx.Matches(content);
    foreach (var match in matches)
        Console.WriteLine(match);

我们异步下载三个网页并打印其HTML标题标签。

tasks.Add(client.GetStringAsync(url));

GetStringAsync创建一个新任务。它向指定的URL发送一个GET请求,并以异步操作的方式返回响应体。

Task.WaitAll(tasks.ToArray());

Task.WaitAll等待所有任务完成执行。

var rx = new Regex(@"<title>\s*(.+?)\s*</title>", RegexOptions.Compiled);
foreach (var content in data)
    var matches = rx.Matches(content);
    foreach (var match in matches)
        Console.WriteLine(match);

在正则表达式的帮助下,我们从检索到的页面中获取标题标签。

$ dotnet run
<title>My html page</title>
<title>Example Domain</title>
<title>httpbin.org</title>

C# HttpClient POST请求

HTTP POST方法向服务器发送数据。请求主体的类型由Content-Type头表示。

$ dotnet add package Newtonsoft.Json

我们需要添加Newtonsoft.Json包来处理JSON数据。

using System;
using System.Text;
using System.Net.Http;
using Newtonsoft.Json;
var person = new Person("John Doe", "gardener");
var json = JsonConvert.SerializeObject(person);
var data = new StringContent(json, Encoding.UTF8, "application/json");
var url = "https://httpbin.org/post";
using var client = new HttpClient();
var response = await client.PostAsync(url, data);
string result = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(result);
record Person(string Name, string Occupation);

在这个例子中,我们发送一个POST请求到 httpbin.org/post 网站,这是一个为开发者提供的在线测试服务。

var person = new Person("John Doe", "gardener");
var json = JsonConvert.SerializeObject(person);
var data = new StringContent(json, Encoding.UTF8, "application/json");

We turn an object into a JSON data with the help of the Newtonsoft.Json package.

var response = await client.PostAsync(url, data);

我们用PostAsync方法发送一个异步POST请求。

string result = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(result);

我们读取返回的数据并将其打印到控制台。

$ dotnet run
  "args": {}, 
  "data": "{\"Name\":\"John Doe\",\"Occupation\":\"gardener\"}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Content-Length": "43", 
    "Content-Type": "application/json; charset=utf-8", 
    "Host": "httpbin.org", 
    "X-Amzn-Trace-Id": "Root=1-5ffd917e-349220186065913c2544d3ba"
  "json": {
    "Name": "John Doe", 
    "Occupation": "gardener"
  "url": "https://httpbin.org/post"
}

C# HttpClient JSON请求

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。这种格式便于人类阅读和书写,也便于机器解析和生成。它是XML的一个不那么冗长、更易读的替代品。JSON的官方互联网媒体类型是application/json。

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using var client = new HttpClient();
client.BaseAddress = new Uri("https://api.github.com");
client.DefaultRequestHeaders.Add("User-Agent", "C# console program");
client.DefaultRequestHeaders.Accept.Add(
        new MediaTypeWithQualityHeaderValue("application/json"));
var url = "repos/symfony/symfony/contributors";
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
var resp = await response.Content.ReadAsStringAsync();
List<Contributor> contributors = JsonConvert.DeserializeObject<List<Contributor>>(resp);
contributors.ForEach(Console.WriteLine);
record Contributor(string Login, short Contributions);

这个例子生成了一个到Github的GET请求。它找出了Symfony框架的顶级贡献者。它使用Newtonsoft.Json来处理JSON。

client.DefaultRequestHeaders.Add("User-Agent", "C# console program");

在请求头中,我们指定用户代理。

client.DefaultRequestHeaders.Accept.Add(
    new MediaTypeWithQualityHeaderValue("application/json"));

在接受头值中,我们告诉JSON是一个可接受的响应类型。

var url = "repos/symfony/symfony/contributors";
HttpResponseMessage response = await client.GetAsync(url);
var resp = await response.Content.ReadAsStringAsync();

我们生成一个请求并异步地读取内容。

List<Contributor> contributors = JsonConvert.DeserializeObject<List<Contributor>>(resp);
contributors.ForEach(Console.WriteLine);

我们用JsonConvert.DeserializeObject方法将JSON响应转化为一个贡献者对象的列表。


C# HttpClient 下载图片

GetByteArrayAsync向指定的Uri发送一个GET请求,并在异步操作中以字节数的形式返回响应体。

using System;
using System.IO;
using System.Net.Http;
using var httpClient = new HttpClient();
var url = "http://webcode.me/favicon.ico";
byte[] imageBytes = await httpClient.GetByteArrayAsync(url);
string documentsPath = System.Environment.GetFolderPath(
        System.Environment.SpecialFolder.Personal);
string localFilename = "favicon.ico";
string localPath = Path.Combine(documentsPath, localFilename);
Console.WriteLine(localPath);
File.WriteAllBytes(localPath, imageBytes);

在这个例子中,我们从 webcode.me 网站上下载一个图像。该图像被写入用户的Documents文件夹中。

byte[] imageBytes = await httpClient.GetByteArrayAsync(url);

GetByteArrayAsync将图像作为一个字节数组返回。

string documentsPath = System.Environment.GetFolderPath(
    System.Environment.SpecialFolder.Personal);

我们用GetFolderPath方法确定Documents文件夹。

File.WriteAllBytes(localPath, imageBytes);

用File.WriteAllBytes方法将这些字节写到磁盘。


C# HttpClient 基本访问认证

在HTTP协议中,基本访问认证是HTTP用户代理(如网络浏览器或控制台应用程序)在提出请求时提供用户名和密码的一种方法。在基本的HTTP认证中,一个请求包含一个头域,其形式为授权。Basic <credentials>,其中credentials是id和密码的base64编码,由一个冒号连接:。

注意:证书没有加密;因此,HTTP基本认证必须与HTTPS协议一起使用。

HTTP基本认证是对网络资源实施访问控制的最简单技术。它不需要cookies、会话标识符或登录页面;相反,HTTP基本认证使用HTTP标头中的标准字段。

using System;
using System.Text;
using System.Net.Http;
using System.Net.Http.Headers;
var userName = "user7";
var passwd = "passwd";
var url = "https://httpbin.org/basic-auth/user7/passwd";
using var client = new HttpClient();
var authToken = Encoding.ASCII.GetBytes($"{userName}:{passwd}");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
        Convert.ToBase64String(authToken));
var result = await client.GetAsync(url);
var content = await result.Content.ReadAsStringAsync();
Console.WriteLine(content);

这个例子将凭证发送到 httpbin.org 网站。

var authToken = Encoding.ASCII.GetBytes($"{userName}:{passwd}");