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

.NET Core中如何从Program.cs向HttpClient添加请求头(最优方案)

问题描述

现有一个注册HttpClient及依赖的扩展类InternalAdminServiceRegister,希望从Program.cs中传递一个请求头参数给该HttpClient,目标是通过AddHttpMessageHandler实现,而非直接在HttpClient配置中添加默认请求头的方式。

原扩展类代码:

public static class InternalAdminServiceRegister
{
    public const string DefaultConfigSectionName = "InternalApisOptions:Admin";

    public static IServiceCollection AddAdminInternalServices(
        this IServiceCollection services,
        IConfiguration configuration,
        string configSectionName = DefaultConfigSectionName)
    {
        services.Configure<AdminOptions>(configuration.GetSection(configSectionName));
        services.AddHttpClient<IInternalAdminService, InternalAdminService>((sp, client) =>
        {
            var options = sp.GetRequiredService<IOptions<AdminOptions>>().Value;
            client.BaseAddress = new Uri(options.ServiceUrl);
            client.Timeout = TimeSpan.FromMilliseconds(options.TimeoutMs);
        }).AddPolicyHandler(GetCircuitBreakerPolicy());
        return services;
    }

    private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
        => HttpPolicyExtensions
            .HandleTransientHttpError()
            .CircuitBreakerAsync(handledEventsAllowedBeforeBreaking: 5, durationOfBreak: TimeSpan.FromSeconds(7));
}

Program.cs调用代码:

var builder = MtsHost.CreateWebApplication(args);
builder.Services.AddAdminInternalServices(builder.Configuration);
解决方案:使用DelegatingHandler实现请求头传递

步骤1:定义自定义DelegatingHandler

创建一个继承自DelegatingHandler的类,用于在每个请求发送前添加指定请求头:

public class RequestHeaderHandler : DelegatingHandler
{
    private readonly KeyValuePair<string, string> _requestHeader;

    public RequestHeaderHandler(string headerName, string headerValue)
    {
        _requestHeader = new KeyValuePair<string, string>(headerName, headerValue);
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // 避免重复添加请求头
        if (!request.Headers.Contains(_requestHeader.Key))
        {
            request.Headers.Add(_requestHeader.Key, _requestHeader.Value);
        }
        return await base.SendAsync(request, cancellationToken);
    }
}

步骤2:修改扩展方法,支持传入请求头并注册Handler

更新AddAdminInternalServices方法,添加可选参数接收请求头信息,并通过AddHttpMessageHandler注册自定义Handler:

public static class InternalAdminServiceRegister
{
    public const string DefaultConfigSectionName = "InternalApisOptions:Admin";

    public static IServiceCollection AddAdminInternalServices(
        this IServiceCollection services,
        IConfiguration configuration,
        string configSectionName = DefaultConfigSectionName,
        (string Name, string Value)? defaultRequestHeader = null)
    {
        services.Configure<AdminOptions>(configuration.GetSection(configSectionName));
        
        var clientBuilder = services.AddHttpClient<IInternalAdminService, InternalAdminService>((sp, client) =>
        {
            var options = sp.GetRequiredService<IOptions<AdminOptions>>().Value;
            client.BaseAddress = new Uri(options.ServiceUrl);
            client.Timeout = TimeSpan.FromMilliseconds(options.TimeoutMs);
        }).AddPolicyHandler(GetCircuitBreakerPolicy());

        // 如果传入了请求头,注册自定义Handler
        if (defaultRequestHeader.HasValue)
        {
            var header = defaultRequestHeader.Value;
            clientBuilder.AddHttpMessageHandler(() => new RequestHeaderHandler(header.Name, header.Value));
        }

        return services;
    }

    private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
        => HttpPolicyExtensions
            .HandleTransientHttpError()
            .CircuitBreakerAsync(handledEventsAllowedBeforeBreaking: 5, durationOfBreak: TimeSpan.FromSeconds(7));
}

步骤3:在Program.cs中传递请求头

调用扩展方法时,传入需要添加的请求头键值对:

var builder = MtsHost.CreateWebApplication(args);
// 传递请求头:键为"endpointService",值为"true"
builder.Services.AddAdminInternalServices(builder.Configuration, defaultRequestHeader: ("endpointService", "true"));

方案优势

  • 相比直接修改DefaultRequestHeaders,DelegatingHandler是在每个请求发送前动态添加请求头,避免了HttpClient复用场景下的全局配置冲突问题。
  • 扩展性更强:后续如需添加多个请求头,只需修改Handler或扩展参数即可,无需改动HttpClient的核心配置逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 04:55:01