.NET 3.1 Azure Function App中DelegatingHandler的SendAsync未被调用
问题根因与修正方案
代码不生效的核心原因有两个,均不会导致编译报错或运行时异常,因此表现为代码可正常运行但自定义Handler始终不触发:
- 重复服务注册导致请求管道完全脱离配置
代码中先通过AddHttpClient<IHtmlDocumentService, HtmlDocumentService>注册了带完整请求管道(含AuthHeaderHandler、重试策略)的Typed HttpClient服务,紧接着又执行builder.Services.AddSingleton<IHtmlDocumentService, HtmlDocumentService>()手动注册了同一接口的实现。
DI容器解析服务时会优先采用最后一次注册的实现,运行时实际加载的HtmlDocumentService是手动注册的单例,该实例不会关联之前配置的带AuthHeaderHandler的HttpClient管道,整个请求链路不会经过AuthHeaderHandler,因此SendAsync方法永远不会被调用。 - AuthHeaderHandler的生命周期不符合HttpClientFactory设计要求
代码中将AuthHeaderHandler注册为单例服务,但HttpClientFactory规定所有挂接在HttpClient管道上的HttpMessageHandler必须为Transient生命周期。若将Handler注册为单例,会导致工厂无法正确追踪Handler生命周期、无法将Handler正确挂载到请求管道,这类问题不会抛出显式异常,只会静默不生效。
修正步骤
- 删除冗余的覆盖式注册:移除
builder.Services.AddSingleton<IHtmlDocumentService, HtmlDocumentService>();这行代码。AddHttpClient<IHtmlDocumentService, HtmlDocumentService>扩展方法内部已自动完成该接口的服务注册,会将配置好管道的HttpClient自动注入到HtmlDocumentService的构造函数中,手动重复注册会直接覆盖原有管道配置。 - 调整AuthHeaderHandler的注册生命周期:将原有的单例注册改为Transient注册,匹配HttpClientFactory对HttpMessageHandler的生命周期要求。
修正后的完整配置代码如下:
public override void Configure(IFunctionsHostBuilder builder) { Config = CdrConfigurationBuilder.BuildConfiguration<Startup>(approotpath: builder.GetContext().ApplicationRootPath); builder.Services.AddSingleton(Config); builder.Services.AddAzureAppConfiguration(); builder.Services.AddSingleton(CdrConfigurationBuilder.ConfigurationRefresher); // 修正:AuthHeaderHandler改为Transient生命周期 builder.Services.AddTransient((c) => new AuthHeaderHandler(Config, apisection: string.Empty, securitysection: "CDR:Services:Security")); builder.Services.AddHttpClient<IHtmlDocumentService, HtmlDocumentService>() .AddHttpMessageHandler<AuthHeaderHandler>() .SetHandlerLifetime(TimeSpan.FromMinutes(5)) .AddPolicyHandler(GetRetryPolicy()); // 已删除冗余的覆盖式服务注册行 builder.Services.AddLogging(); }
验证方式
修改完成后可通过两种方式确认Handler是否正常生效:
- 在HtmlDocumentService的构造函数入口打断点,检查注入的HttpClient实例携带的请求管道中是否包含AuthHeaderHandler
- 在AuthHeaderHandler的SendAsync方法入口添加日志输出,发起业务请求后确认日志是否正常打印
内容的提问来源于stack exchange,提问作者Jude Fisher
相关产品推荐
相关产品推荐

