You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HttpClientFactory配置客户端时触发请求已启动错误的排查

问题原因与解决方案

核心问题

你遇到的错误根源是在AddHttpClient的配置委托中使用了async/await。AddHttpClient的第二个参数预期是同步的Action<HttpClient>,如果传入异步委托(Func<HttpClient, Task>),框架会以"fire-and-forget"的方式执行它——在你await jwtTokenProvider.GetTokenAsync()的间隙,HttpClient实例已经被框架内部初始化甚至返回给调用方,后续再修改DefaultRequestHeaders、BaseAddress等属性时,就会触发实例已启动请求的错误。

解决方案

方案1:用自定义DelegatingHandler注入Token(推荐)

把异步获取Token的逻辑移到请求发送前的拦截器中,避免在客户端初始化阶段执行异步操作:

public class TokenHandler : DelegatingHandler
{
    private readonly IJwtTokenProvider _jwtTokenProvider;
    private readonly IConfigurationSection _appSettingsSectionIdentity;

    public TokenHandler(IJwtTokenProvider jwtTokenProvider, IConfigurationSection appSettingsSectionIdentity)
    {
        _jwtTokenProvider = jwtTokenProvider;
        _appSettingsSectionIdentity = appSettingsSectionIdentity;
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var tokenData = await _jwtTokenProvider.GetTokenAsync(_appSettingsSectionIdentity);
        if (tokenData is null || !tokenData.IsValid)
            throw new TechnicalErrorException("Can't get a token xxx");

        // 替换为实际的Token格式,比如 $"Bearer {tokenData.Token}"
        request.Headers.TryAddWithoutValidation("Authorization", "xx"); 
        return await base.SendAsync(request, cancellationToken);
    }
}

然后注册Handler和HttpClient:

services.AddTransient<TokenHandler>();
services.AddHttpClient("xxx")
    .ConfigureHttpClient(client =>
    {
        client.BaseAddress = new Uri(baseAddress);
    })
    .AddHttpMessageHandler<TokenHandler>()
    .AddPolicyHandler(PollyPolicys.xxx());

方案2:使用HttpClient时手动配置Token

如果不想自定义Handler,也可以在每次获取客户端后,先异步获取Token再配置请求头:

var httpClient = _httpClientFactory.CreateClient("xxx");
var tokenData = await jwtTokenProvider.GetTokenAsync(appSettingsSectionIdentity);
if (tokenData is null || !tokenData.IsValid)
    throw new TechnicalErrorException("Can't get a token xxx");

httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "xx");
// 后续执行请求逻辑

额外说明

  • 你之前尝试的CancelPendingRequests()、移除Polly策略无效,因为根本问题是异步配置委托导致客户端提前初始化。
  • BaseAddress建议放在同步的ConfigureHttpClient委托中设置,避免在异步逻辑中修改客户端属性。

内容的提问来源于stack exchange,提问作者steb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 21:41:04