IHttpClientFactory in .NetCore _ 使用场景 & HttpRequest

Make HTTP requests using IHttpClientFactory in ASP.NET Core | Microsoft Docs

 

There are several ways IHttpClientFactory can be used in an app:

The best approach depends upon the app's requirements.

 

Basic usage

Register IHttpClientFactory by calling AddHttpClient in Program.cs:

  An IHttpClientFactory can be requested using dependency injection (DI). The following code uses IHttpClientFactory to create an HttpClient instance:

 

 

 

 Using IHttpClientFactory like in the preceding example is a good way to refactor an existing app. It has no impact on how HttpClient is used. In places where HttpClient instances are created in an existing app, replace those occurrences with calls to CreateClient.

 

Named clients

Named clients are a good choice when:

  • The app requires many distinct uses of HttpClient.
  • Many HttpClients have different configuration.

Specify configuration for a named HttpClient during its registration in Program.cs:

builder.Services.AddHttpClient("GitHub", httpClient =>
{
    httpClient.BaseAddress = new Uri("https://api.github.com/");

    // using Microsoft.Net.Http.Headers;
    // The GitHub API requires two headers.
    httpClient.DefaultRequestHeaders.Add(
        HeaderNames.Accept, "application/vnd.github.v3+json");
    httpClient.DefaultRequestHeaders.Add(
        HeaderNames.UserAgent, "HttpRequestsSample");
});

  

In the preceding code the client is configured with:

  • The base address https://api.github.com/.
  • Two headers required to work with the GitHub API.

CreateClient

Each time CreateClient is called:

  • A new instance of HttpClient is created.
  • The configuration action is called.

To create a named client, pass its name into CreateClient:

 

 

 In the preceding code, the request doesn't need to specify a hostname. The code can pass just the path, since the base address configured for the client is used.

 

Typed clients

Typed clients:

  • Provide the same capabilities as named clients without the need to use strings as keys.
  • Provides IntelliSense and compiler help when consuming clients.
  • Provide a single location to configure and interact with a particular HttpClient. For example, a single typed client might be used:
    • For a single backend endpoint.
    • To encapsulate all logic dealing with the endpoint.
  • Work with DI and can be injected where required in the app.

A typed client accepts an HttpClient parameter in its constructor:

 

 

 

In the preceding code:

  • The configuration is moved into the typed client.
  • The provided HttpClient instance is stored as a private field.

API-specific methods can be created that expose HttpClient functionality. For example, the GetAspNetCoreDocsBranches method encapsulates code to retrieve docs GitHub branches.

The following code calls AddHttpClient in Program.cs to register the GitHubService typed client class:

builder.Services.AddHttpClient<GitHubService>();

  The typed client is registered as transient with DI. In the preceding code, AddHttpClient registers GitHubService as a transient service. This registration uses a factory method to:

  1. Create an instance of HttpClient.
  2. Create an instance of GitHubService, passing in the instance of HttpClient to its constructor.

The typed client can be injected and consumed directly:

 

 

 The configuration for a typed client can also be specified during its registration in Program.cs, rather than in the typed client's constructor:

builder.Services.AddHttpClient<GitHubService>(httpClient =>
{
    httpClient.BaseAddress = new Uri("https://api.github.com/");

    // ...
});

  

Generated clients

IHttpClientFactory can be used in combination with third-party libraries such as Refit. Refit is a REST library for .NET. It converts REST APIs into live interfaces. Call AddRefitClient to generate a dynamic implementation of an interface, which uses HttpClient to make the external HTTP calls.

A custom interface represents the external API:

 

public interface IGitHubClient
{
    [Get("/repos/dotnet/AspNetCore.Docs/branches")]
    Task<IEnumerable<GitHubBranch>> GetAspNetCoreDocsBranchesAsync();
}

  

Call AddRefitClient to generate the dynamic implementation and then call ConfigureHttpClient to configure the underlying HttpClient:

 

 

 

Use DI to access the dynamic implementation of IGitHubClient:

 

 

 

Make POST, PUT, and DELETE requests

In the preceding examples, all HTTP requests use the GET HTTP verb. HttpClient also supports other HTTP verbs, including:

  • POST
  • PUT
  • DELETE
  • PATCH

For a complete list of supported HTTP verbs, see HttpMethod.

 

The following example shows how to make an HTTP POST request:

public async Task CreateItemAsync(TodoItem todoItem)
{
    var todoItemJson = new StringContent(
        JsonSerializer.Serialize(todoItem),
        Encoding.UTF8,
        Application.Json); // using static System.Net.Mime.MediaTypeNames;

    using var httpResponseMessage =
        await _httpClient.PostAsync("/api/TodoItems", todoItemJson);

    httpResponseMessage.EnsureSuccessStatusCode();
}

  

In the preceding code, the CreateItemAsync method:

  • Serializes the TodoItem parameter to JSON using System.Text.Json.
  • Creates an instance of StringContent to package the serialized JSON for sending in the HTTP request's body.
  • Calls PostAsync to send the JSON content to the specified URL. This is a relative URL that gets added to the HttpClient.BaseAddress.
  • Calls EnsureSuccessStatusCode to throw an exception if the response status code doesn't indicate success.

HttpClient also supports other types of content. For example, MultipartContent and StreamContent. For a complete list of supported content, see HttpContent.

 

 

The following example shows an HTTP PUT request:

public async Task SaveItemAsync(TodoItem todoItem)
{
    var todoItemJson = new StringContent(
        JsonSerializer.Serialize(todoItem),
        Encoding.UTF8,
        Application.Json);

    using var httpResponseMessage =
        await _httpClient.PutAsync($"/api/TodoItems/{todoItem.Id}", todoItemJson);

    httpResponseMessage.EnsureSuccessStatusCode();
}

  The preceding code is similar to the POST example. The SaveItemAsync method calls PutAsync instead of PostAsync.

 

The following example shows an HTTP DELETE request:

 

public async Task DeleteItemAsync(long itemId)
{
    using var httpResponseMessage =
        await _httpClient.DeleteAsync($"/api/TodoItems/{itemId}");

    httpResponseMessage.EnsureSuccessStatusCode();
}

  In the preceding code, the DeleteItemAsync method calls DeleteAsync. Because HTTP DELETE requests typically contain no body, the DeleteAsync method doesn't provide an overload that accepts an instance of HttpContent.

To learn more about using different HTTP verbs with HttpClient, see HttpClient.

 

posted @ 2022-07-11 17:37  PanPan003  阅读(37)  评论(0编辑  收藏  举报