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
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()
方法将 GET 请求作为异步操作发送到指定的 Uri。 await
运算符会暂停对异步方法的评估,直到异步操作完成为止。 异步操作完成后,await
操作符将返回操作结果(如果有)。
$ dotnet run
OK
我们得到 200 OK 状态码; 网站开通了。
C# HttpClient
GET 请求
GET 方法请求指定资源的表示形式。
Program.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 代码。
var content = await client.GetStringAsync("http://webcode.me");
GetStringAsync()
发送 GET 请求到指定的 Uri,并在异步操作中将响应主体作为字符串返回。
$ 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
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 请求。
$ 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
标头指示。
$ dotnet add package Newtonsoft.Json
我们需要添加Newtonsoft.Json
包来处理 JSON 数据。
Program.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
网站,该网站是面向开发人员的在线测试服务。
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 数据。
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"
},
"json": {
"Name": "John Doe",
"Occupation": "gardener"
},
...
"url": "https://httpbin.org/post"
}
C# HttpClient
JSON 请求
JSON(JavaScript 对象表示法)是一种轻量级的数据交换格式。 这种格式对于人类来说很容易读写,对于机器来说,解析和生成都很容易。 它是 XML 的较不冗长且更易读的替代方案。 JSON 的官方 Internet 媒体类型为application/json
。
Program.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。
client.DefaultRequestHeaders.Add("User-Agent", "C# console program");
在请求标头中,我们指定用户代理。
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
在 accept 标头值中,我们告诉 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 响应转换为Contributor
对象的列表。
C# HttpClient
下载图像
GetByteArrayAsync()
将 GET 请求发送到指定的 Uri,并在异步操作中将响应主体作为字节数组返回。
Program.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
文件夹。
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 用户代理(例如 Web 浏览器或控制台应用)在发出请求时提供用户名和密码的方法。 在基本 HTTP 身份验证中,请求包含Authorization: Basic <credentials>
形式的标头字段,其中凭据是由单个冒号:
连接的 id 和 password 的 base64 编码。
Note: The credentials are not encrypted; therefore, HTTP basic authentication must be used with the HTTPS protocol.
HTTP 基本身份验证是用于实施对 Web 资源的访问控制的最简单技术。 它不需要 cookie,会话标识符或登录页面; 相反,HTTP 基本身份验证使用 HTTP 标头中的标准字段。
Program.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
网站。
var authToken = Encoding.ASCII.GetBytes($"{userName}:{passwd}");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(authToken));
在这里,我们构建身份验证标头。
var url = "https://httpbin.org/basic-auth/user7/passwd";
该 URL 包含身份验证详细信息,因为我们在httpbin.org
网站上对其进行了测试。 这样,我们不需要设置自己的服务器。 当然,身份验证详细信息永远不会放在 URL 中。
$ dotnet run
{
"authenticated": true,
"user": "user7"
}