加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-core-2.1 – 配置HttpClientFactory以使用当前请求上下

发布时间:2020-12-16 06:40:44 所属栏目:asp.Net 来源:网络整理
导读:使用ASP.NET Core 2.1中的新 HttpClientFactory,使用基本URL,默认标题等配置自定义HTTP客户端非常容易. 但是,我还没有找到一种方法来集中配置,让我从当前请求上下文中注入头文件.例如,考虑使用Authorization标头调用的服务,我希望将其传递给所有底层服务.能
使用ASP.NET Core 2.1中的新 HttpClientFactory,使用基本URL,默认标题等配置自定义HTTP客户端非常容易.

但是,我还没有找到一种方法来集中配置,让我从当前请求上下文中注入头文件.例如,考虑使用Authorization标头调用的服务,我希望将其传递给所有底层服务.能够在Startup类中的服务上的.AddHttpClient()调用中配置它会很棒,但我无法弄清楚如何从那里获取请求上下文.

有任何想法吗?

解决方法

通过这个答案,我得到了多个答案.我认为第一种方法是你正在寻找的,第二种方法是一个很好的选择.

要配置多个客户端,可以使用named clients.这些客户端注册为瞬态.使用DI获取有权访问请求上下文的服务.

为此,我们需要IHttpContextAccessor.在这种情况下,您不必自己注册,因为Identity已经为您执行此操作.

否则在启动时添加以下行:

services.AddHttpContextAccessor();

接下来我们可以配置命名客户端“github”:

services.AddHttpClient("github",c =>
{
    // access the DI container
    var serviceProvider = services.BuildServiceProvider();
    // Find the HttpContextAccessor service
    var httpContextAccessor = serviceProvider.GetService<IHttpContextAccessor>();
    // Get the bearer token from the request context (header)
    var bearerToken = httpContextAccessor.HttpContext.Request
                          .Headers["Authorization"]
                          .FirstOrDefault(h => h.StartsWith("bearer ",StringComparison.InvariantCultureIgnoreCase));

    // Add authorization if found
    if (bearerToken != null)
        c.DefaultRequestHeaders.Add("Authorization",bearerToken);

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

像这样调用客户端:

public class MyController : ControllerBase
{
    private readonly IHttpClientFactory _clientFactory;

    public MyController(IHttpClientFactory clientFactory)
    {
        _clientFactory = clientFactory;
    }

    public async Task<ActionResult> StartCall()
    {
        var client = _clientFactory.CreateClient("github");
        var response = await client.GetAsync("/repos/aspnet/docs/issues");
    }
}

另一种选择是使用Typed客户端.这是一个简短的例子.有关完整示例,请查看link.

注册IHttpContextAccessor:

services.AddHttpContextAccessor();

创建一个类型化的客户端.我添加了两个选项来添加设置.一个通过请求上下文,一个通过单例类:

public class GitHubService
{
    public HttpClient Client { get; }

    public GitHubService(HttpClient client,HttpClientSettings httpClientSettings,IHttpContextAccessor httpContextAccessor)
    {
        var bearerToken = httpContextAccessor.HttpContext.Request
                              .Headers["Authorization"]
                              .FirstOrDefault(h => h.StartsWith("bearer ",StringComparison.InvariantCultureIgnoreCase));

        // Add authorization if found
        if (bearerToken != null)
            client.DefaultRequestHeaders.Add("Authorization",bearerToken);

        // Or the value from httpClientSettings:
        client.DefaultRequestHeaders.Add("Authorization",httpClientSettings.BearerToken);

        client.BaseAddress = new Uri("https://api.github.com/");
        client.DefaultRequestHeaders.Add("Accept","application/vnd.github.v3+json"); // GitHub API versioning
        client.DefaultRequestHeaders.Add("User-Agent","HttpClientFactory-Sample"); // GitHub requires a user-agent

        Client = client;
    }
}

注册客户:

// The typed client is registered as transient with DI.
services.AddHttpClient<GitHubService>();

请注意,下面的代码只是一个例子.由于令牌无法在客户端中持久化,因此您可以使用共享的HttpClientSettings:

services.AddSingleton<HttpClientSettings>();

HttpClientSettings的位置是:

public class HttpClientSettings
{
    public string BearerToken { get; set; }
}

您可以像这样使用客户端:

public class MyController : ControllerBase
{
    private readonly GitHubService _gitHubService;

    public MyController(GitHubService gitHubService)
    {
        _gitHubService = gitHubService;
    }

    public async Task<ActionResult> StartCall()
    {
        var response = await _gitHubService.Client.GetAsync("/repos/aspnet/docs/issues");

    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读