Blazor TypeClient `AddHttpMessageHandler` 发出 `InvalidOperationException` (ValueFactory 尝试访问此实例的 Value 属性。)

问题描述 投票:0回答:1

我尝试应用 ASP.NET Core Blazor WebAssembly 额外的安全方案,键入

HttpClient
,并使用 OIDC 身份验证,如下所示,

// Blazor WebAssembly 'Program.cs'
public static async Task Main(string[] args)
{
    var builder = WebAssemblyHostBuilder.CreateDefault(args);
    builder.RootComponents.Add<App>("#app");

    builder.Services.AddHttpClient<ApplicationHttpClient>(nameof(ApplicationHttpClient), client =>
    {
        client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress);
    }).AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

    builder.Services.AddScoped(serviceProvider =>
    {
        return serviceProvider.GetRequiredService<IHttpClientFactory>().CreateClient(nameof(ApplicationHttpClient));
    });

    builder.Services.AddOidcAuthentication<RemoteAuthenticationState, RemoteUserAccount>(options =>
    {
        builder.Configuration.Bind("Google", options.ProviderOptions);
        options.ProviderOptions.DefaultScopes.Add("email");
    }).AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, RemoteUserAccount, CustomAccountClaimsPrincipalFactory>();

    await builder.Build().RunAsync();
}

如果构建并运行,我遇到了以下异常,

crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: ValueFactory attempted to access the Value property of this instance.
System.InvalidOperationException: ValueFactory attempted to access the Value property of this instance.
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ViaFactory(LazyThreadSafetyMode mode) in System.Private.CoreLib.dll:token 0x6000fa7+0x43
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor) in System.Private.CoreLib.dll:token 0x6000fa8+0x22
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].CreateValue() in System.Private.CoreLib.dll:token 0x6000fad+0x74
   at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].get_Value() in System.Private.CoreLib.dll:token 0x6000fb3+0xa
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandler(String name) in Microsoft.Extensions.Http.dll:token 0x6000065+0xe
   at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateClient(String name) in Microsoft.Extensions.Http.dll:token 0x6000064+0xe

如果我注释掉

AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>()
,它会像以前一样运行良好。

.NET 6.0.100-预览版.5 21302.13
Visual Studio 2019 16.10.2

重现

Github

  1. 运行“TypedHttpClient.Server”
  2. 导航至“获取数据”菜单
  3. 查看控制台错误消息。

异常来自

DefaultHttpClientFactory.cs

// Microsoft.Extensions.Http.DefaultHttpClientFactory.cs
public HttpMessageHandler CreateHandler(string name)
{
    if (name == null)
    {
        throw new ArgumentNullException(nameof(name));
    }

    // Here
    ActiveHandlerTrackingEntry entry = _activeHandlers.GetOrAdd(name, _entryFactory).Value;

    StartHandlerEntryTimer(entry);

    return entry.Handler;
}

2021.06.24更新

我用

AddHttpMessageHandler
测试
NoobHandler
方法,如下所示。

public class NoobHandler : DelegatingHandler
{

}

改为

BaseAddressAuthorizationMessageHandler
,添加
NoobHandler
即可。

builder.Services.AddScoped<NoobHandler>();
builder.Services.AddHttpClient<WeatherForecastClient>(nameof(WeatherForecastClient),
    client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<NoobHandler>();

因此,我怀疑

BaseAddressAuthorizationMessageHandler
构造函数没有创建实例,但
DefaultHttpClientFactory
尝试访问值。

c# .net-core blazor blazor-webassembly
1个回答
0
投票

这是我一直在寻找的问题根源: https://github.com/dotnet/aspnetcore/issues/33787#issuecomment-1788625106

HttpClient 的循环依赖注入可能会导致这种情况。比如这样:

builder.Services.AddScoped<AuthenticationService>();
builder.Services.AddScoped<AppHttpMessageHandler>();
builder.Services.AddHttpClient("MyApi", client => client.BaseAddress = new Uri(ApiBaseAddress))
    .AddHttpMessageHandler<AppHttpMessageHandler>();

如果您尝试将

HttpClient
注入
AuthenticationService
AppHttpMessageHandler
,您将收到此错误:
ValueFactory attempted to access the Value property of this instance

尝试使用

IHttpClientFactory
独立服务来解决此问题。

© www.soinside.com 2019 - 2024. All rights reserved.