ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# C# `HttpClient`教程 > 原文: [https://zetcode.com/csharp/httpclient/](https://zetcode.com/csharp/httpclient/) C# `HttpClient`教程展示了如何使用 C# 中的`HttpClient`创建 HTTP 请求。 在示例中,我们创建简单的 GET 和 POST 请求。 超文本传输​​协议(HTTP)是用于分布式,协作式超媒体信息系统的应用协议。 HTTP 是万维网数据通信的基础。 `HttpClient`是用于从 URI 标识的资源发送 HTTP 请求和接收 HTTP 响应的基类。 ## C# `HttpClient`状态码 HTTP 响应状态代码指示特定的 HTTP 请求是否已成功完成。 响应分为五类: * 信息响应(100–199) * 成功响应(200–299) * 重定向(300–399) * 客户端错误(400–499) * 服务器错误(500–599) `Program.cs` ```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 请求。 我们获得了请求的状态码。 ```cs using var client = new HttpClient(); ``` 创建一个新的`HttpClient`。 ```cs var result = await client.GetAsync("http://webcode.me"); ``` `GetAsync()`方法将 GET 请求作为异步操作发送到指定的 Uri。 `await`运算符会暂停对异步方法的求值,直到异步操作完成为止。 异步操作完成后,`await`操作符将返回操作结果(如果有)。 ```cs $ dotnet run OK ``` 我们得到 200 OK 状态码; 网站开通了。 ## C# `HttpClient` GET 请求 GET 方法请求指定资源的表示形式。 `Program.cs` ```cs 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 代码。 ```cs var content = await client.GetStringAsync("http://webcode.me"); ``` `GetStringAsync()`发送 GET 请求到指定的 Uri,并在异步操作中将响应主体作为字符串返回。 ```cs $ dotnet run <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My html page</title> </head> <body> <p> Today is a beautiful day. We go swimming and fishing. </p> <p> Hello there. How are you? </p> </body> </html> ``` 这是输出。 ## C# `HttpClient` HEAD 请求 如果将使用 HTTP GET 方法请求指定的资源,则 HTTP HEAD 方法请求返回的标头。 `Program.cs` ```cs using System; using System.Net.Http; using System.Threading.Tasks; namespace HttpClientHead { class Program { static async Task Main(string[] args) { var url = "http://webcode.me"; using var client = new HttpClient(); var result = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url)); Console.WriteLine(result); } } } ``` 该示例发出 HEAD 请求。 ```cs $ dotnet run StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers: { Server: nginx/1.6.2 Date: Sat, 12 Oct 2019 19:55:14 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` POST 请求 HTTP POST 方法将数据发送到服务器。 请求正文的类型由`Content-Type`标头指示。 ```cs $ dotnet add package Newtonsoft.Json ``` 我们需要添加`Newtonsoft.Json`包来处理 JSON 数据。 `Program.cs` ```cs using System; using System.Text; using System.Net.Http; using System.Threading.Tasks; using Newtonsoft.Json; namespace HttpClientPost { class Person { public string Name { get; set; } public string Occupation { get; set; } public override string ToString() { return $"{Name}: {Occupation}"; } } class Program { static async Task Main(string[] args) { var person = new Person(); person.Name = "John Doe"; person.Occupation = "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); } } } ``` 在示例中,我们将 POST 请求发送到`https://httpbin.org/post`网站,该网站是面向开发者的在线测试服务。 ```cs var person = new Person(); person.Name = "John Doe"; person.Occupation = "gardener"; var json = JsonConvert.SerializeObject(person); var data = new StringContent(json, Encoding.UTF8, "application/json"); ``` 我们借助`Newtonsoft.Json`包将对象转换为 JSON 数据。 ```cs var response = await client.PostAsync(url, data); ``` 我们使用`PostAsync()`方法发送异步 POST 请求。 ```cs string result = response.Content.ReadAsStringAsync().Result; Console.WriteLine(result); ``` 我们读取返回的数据并将其打印到控制台。 ```cs $ 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" }, "json": { "Name": "John Doe", "Occupation": "gardener" }, ... "url": "https://httpbin.org/post" } ``` This is the output. ## C# `HttpClient` JSON 请求 JSON(JavaScript 对象表示法)是一种轻量级的数据交换格式。 这种格式对于人类来说很容易读写,对于机器来说,解析和生成都很容易。 它是 XML 的较不冗长且更易读的替代方案。 JSON 的官方互联网媒体类型为`application/json`。 `Program.cs` ```cs using System; using System.Threading.Tasks; using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; using Newtonsoft.Json; namespace HttpClientJson { class Contributor { public string Login { get; set; } public short Contributions { get; set; } public override string ToString() { return $"{Login,20}: {Contributions} contributions"; } } class Program { private static async Task Main() { 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); } } } ``` 该示例生成对 Github 的 GET 请求。 它找出了 Symfony 框架的主要贡献者。 它使用`Newtonsoft.Json`处理 JSON。 ```cs client.DefaultRequestHeaders.Add("User-Agent", "C# console program"); ``` 在请求标头中,我们指定用户代理。 ```cs client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json")); ``` 在`accept`标头值中,我们告诉 JSON 是可接受的响应类型。 ```cs var url = "repos/symfony/symfony/contributors"; HttpResponseMessage response = await client.GetAsync(url); var resp = await response.Content.ReadAsStringAsync(); ``` 我们生成一个请求并异步读取内容。 ```cs List<Contributor> contributors = JsonConvert.DeserializeObject<List<Contributor>>(resp); contributors.ForEach(Console.WriteLine); ``` 我们使用`JsonConvert.DeserializeObject()`方法将 JSON 响应转换为`Contributor`对象的列表。 ## C# `HttpClient`下载图像 `GetByteArrayAsync()`将 GET 请求发送到指定的 Uri,并在异步操作中将响应主体作为字节数组返回。 `Program.cs` ```cs using System; using System.IO; using System.Net.Http; using System.Threading.Tasks; namespace HttpClientDownloadImage { class Program { static async Task Main(string[] args) { 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); File.WriteAllBytes(localPath, imageBytes); } } } ``` 在示例中,我们从`webcode.me`网站下载图像。 图像被写入用户的`Documents`文件夹。 ```cs byte[] imageBytes = await httpClient.GetByteArrayAsync(url); ``` `GetByteArrayAsync()`将图像作为字节数组返回。 ```cs string documentsPath = System.Environment.GetFolderPath( System.Environment.SpecialFolder.Personal); ``` 我们用`GetFolderPath()`方法确定`Documents`文件夹。 ```cs File.WriteAllBytes(localPath, imageBytes); ``` 使用`File.WriteAllBytes()`方法将字节写入磁盘。 ## C# `HttpClient` 基本认证 在 HTTP 协议中,基本访问认证是 HTTP 用户代理(例如 Web 浏览器或控制台应用)在发出请求时提供用户名和密码的方法。 在基本 HTTP 认证中,请求包含`Authorization: Basic <credentials>`形式的标头字段,其中凭据是由单个冒号`:`连接的 id 和密码的 base64 编码。 > **注意**:凭证未加密; 因此,必须将 HTTP 基本认证与 HTTPS 协议一起使用。 HTTP 基本认证是用于实现对 Web 资源的访问控制的最简单技术。 它不需要 cookie,会话标识符或登录页面; 相反,HTTP 基本认证使用 HTTP 标头中的标准字段。 `Program.cs` ```cs using System; using System.Text; using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; namespace HttpClientAuth { class Program { static async Task Main(string[] args) { 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`网站。 ```cs var authToken = Encoding.ASCII.GetBytes($"{userName}:{passwd}"); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authToken)); ``` 在这里,我们构建认证标头。 ```cs var url = "https://httpbin.org/basic-auth/user7/passwd"; ``` 该 URL 包含认证详细信息,因为我们在`httpbin.org`网站上对其进行了测试。 这样,我们不需要设置自己的服务器。 当然,认证详细信息永远不会放在 URL 中。 ```cs $ dotnet run { "authenticated": true, "user": "user7" } ``` This is the output. 在本教程中,我们使用 C# `HttpClient`创建 HTTP 请求。 您可能也对以下相关教程感兴趣: [C# 教程](/lang/csharp/), [MySQL C# 教程](/db/mysqlcsharptutorial/), [C# 中的日期和时间](/articles/csharpdatetime/), [C# ](/articles/csharpreadwebpage/)或 [C# Winforms 教程](/gui/csharpwinforms/)。