在 ASP.NET Core 中使用 IHttpClientFactory 發出 HTTP 請求

可以註冊 IHttpClientFactory 並將其用於配置和創建應用中的 HttpClient 實例。 IHttpClientFactory 的優勢如下:

提供一箇中心位置,用於命名和配置邏輯 HttpClient 實例。 例如,可註冊和配置名爲 github 的客戶端,使其訪問 GitHub 。 可以註冊一個默認客戶端用於一般性訪問。
通過 HttpClient 中的委託處理程序來編碼出站中間件的概念。 提供基於 Polly 的中間件的擴展,以利用 HttpClient 中的委託處理程序。
管理基礎 HttpClientMessageHandler 實例的池和生存期。 自動管理可避免手動管理 HttpClient 生存期時出現的常見 DNS(域名系統)問題。
(通過 ILogger)添加可配置的記錄體驗,以處理工廠創建的客戶端發送的所有請求。

模式

在應用中可以通過以下多種方式使用 IHttpClientFactory

最佳方法取決於應用要求。

基本用法

可以通過調用 AddHttpClient 來註冊 IHttpClientFactory

1

2

3

4

5

6

7

8

9

10

11

12

13

public class Startup

{

    public Startup(IConfiguration configuration)

    {

        Configuration = configuration;

    }

 

    public IConfiguration Configuration { get; }

 

    public void ConfigureServices(IServiceCollection services)

    {

        services.AddHttpClient();

        // Remaining code deleted for brevity.

可以使用依賴項注入 (DI) 來請求 IHttpClientFactory。 以下代碼使用 IHttpClientFactory 來創建 HttpClient 實例:

public class BasicUsageModel : PageModel
{
    private readonly IHttpClientFactory _clientFactory;
 
    public IEnumerable<GitHubBranch> Branches { get; private set; }
 
    public bool GetBranchesError { get; private set; }
 
    public BasicUsageModel(IHttpClientFactory clientFactory)
    {
        _clientFactory = clientFactory;
    }
 
    public async Task OnGet()
    {
        var request = new HttpRequestMessage(HttpMethod.Get,
            "https://api.github.com/repos/aspnet/AspNetCore.Docs/branches");
        request.Headers.Add("Accept", "application/vnd.github.v3+json");
        request.Headers.Add("User-Agent", "HttpClientFactory-Sample");
 
        var client = _clientFactory.CreateClient();
 
        var response = await client.SendAsync(request);
 
        if (response.IsSuccessStatusCode)
        {
            using var responseStream = await response.Content.ReadAsStreamAsync();
            Branches = await JsonSerializer.DeserializeAsync
                <IEnumerable<GitHubBranch>>(responseStream);
        }
        else
        {
            GetBranchesError = true;
            Branches = Array.Empty<GitHubBranch>();
        }
    }
}

像前面的示例一樣,使用 IHttpClientFactory 是重構現有應用的好方法。 這不會影響 HttpClient 的使用方式。 在現有應用中創建 HttpClient 實例的位置,使用對 CreateClient的調用替換這些匹配項。

命名客戶端

在以下情況下,命名客戶端是一個不錯的選擇:

  • 應用需要 HttpClient 的許多不同用法。
  • 許多 HttpClient 具有不同的配置。

可以在 Startup.ConfigureServices 中註冊時指定命名 HttpClient 的配置:

services.AddHttpClient("github", c =>
{
    c.BaseAddress = new Uri("https://api.github.com/");
    // Github API versioning  www.zyiz.net
    c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
    // Github requires a user-agent
    c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
});

在上述代碼中,客戶端配置如下:

  • 基址爲 https://api.github.com/
  • 使用 GitHub API 需要的兩個標頭。

CreateClient

每次調用 CreateClient時:

  • 創建 HttpClient 的新實例。
  • 調用配置操作。

要創建命名客戶端,請將其名稱傳遞到 CreateClient 中:

public class NamedClientModel : PageModel
{
    private readonly IHttpClientFactory _clientFactory;
 
    public IEnumerable<GitHubPullRequest> PullRequests { get; private set; }
 
    public bool GetPullRequestsError { get; private set; }
 
    public bool HasPullRequests => PullRequests.Any();
 
    public NamedClientModel(IHttpClientFactory clientFactory)
    {
        _clientFactory = clientFactory;
    }
 
    public async Task OnGet()
    {
        var request = new HttpRequestMessage(HttpMethod.Get,
            "repos/aspnet/AspNetCore.Docs/pulls");
 
        var client = _clientFactory.CreateClient("github");
 
        var response = await client.SendAsync(request);
 
        if (response.IsSuccessStatusCode)
        {
            using var responseStream = await response.Content.ReadAsStreamAsync();
            PullRequests = await JsonSerializer.DeserializeAsync
                    <IEnumerable<GitHubPullRequest>>(responseStream);
        }
        else
        {
            GetPullRequestsError = true;
            PullRequests = Array.Empty<GitHubPullRequest>();
        }
    }
}

在上述代碼中,請求不需要指定主機名。 代碼可以僅傳遞路徑,因爲採用了爲客戶端配置的基址。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章