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

在Blazor WASM中用Refit添加令牌时遇类型转换异常

问题分析与解决:Blazor WebAssembly中API授权客户端的类型转换错误

问题重现

注册代码

var builder = WebAssemblyHostBuilder.CreateDefault(args);

builder.Services.AddHttpClient("myApi").AddHttpMessageHandler<CustomAuthorizationMessageHandler>();
builder.Services.AddScoped<CustomAuthorizationMessageHandler>();
builder.Services.AddAuthorizationCore();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddScoped<AuthenticationStateProvider, PersistentAuthenticationStateProvider>();
builder.Services.AddApiAuthorization();

builder.Services.AddRefitClient<IWeatherApi>()
    .ConfigureHttpClient(c =>
    {
        c.BaseAddress = new Uri("https://localhost:7252");

    })
    .AddHttpMessageHandler(sp => sp.GetRequiredService<AuthorizationMessageHandler>()
            .ConfigureHandler(new[] { "https://localhost:7252" }));

尝试的替代调用方式

RestService.For<IWeatherApi>(HttpClientFactory.CreateClient("myApi"));

错误信息

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Specified cast is not valid.
System.InvalidCastException: Specified cast is not valid.

at Microsoft.Extensions.DependencyInjection.WebAssemblyAuthenticationServiceCollectionExtensions.<>c__0`3[[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationState, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteUserAccount, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.ApiAuthorizationProviderOptions, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].b__0_0(IServiceProvider sp)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)

问题原因

核心矛盾是**PersistentAuthenticationStateProvider与AddApiAuthorization()的默认服务实现不兼容**:

  • AddApiAuthorization()会自动注册一套完整的远程认证服务,包括特定的AuthenticationStateProvider子类(RemoteAuthenticationStateProvider)
  • 你手动注册的PersistentAuthenticationStateProvider未继承该子类,框架尝试将其强制转换为所需类型时抛出转换异常。

解决步骤

1. 调整认证状态提供者注册

方案一:使用AddApiAuthorization()默认配置(推荐)

移除手动替换的PersistentAuthenticationStateProvider,让框架自动配置兼容的认证服务:

// 移除该行手动注册
// builder.Services.AddScoped<AuthenticationStateProvider, PersistentAuthenticationStateProvider>();

// 保留AddApiAuthorization(),它会自动注册正确的AuthenticationStateProvider
builder.Services.AddApiAuthorization();

方案二:自定义兼容的状态提供者

若必须使用自定义逻辑,需确保类继承自框架要求的基类:

public class CustomPersistentAuthenticationStateProvider : RemoteAuthenticationStateProvider<RemoteAuthenticationState, RemoteUserAccount>
{
    // 实现自定义状态管理逻辑
}

// 注册时替换对应服务类型
builder.Services.AddScoped<RemoteAuthenticationStateProvider<RemoteAuthenticationState, RemoteUserAccount>, CustomPersistentAuthenticationStateProvider>();

2. 统一HttpClient认证处理器

保持命名HttpClient与Refit客户端的认证逻辑一致:

  • 如果使用自定义CustomAuthorizationMessageHandler,Refit客户端也应添加该处理器
  • 如果依赖AddApiAuthorization()的默认处理器,需确保正确关联

调整Refit客户端注册示例:

builder.Services.AddRefitClient<IWeatherApi>()
    .ConfigureHttpClient(c => c.BaseAddress = new Uri("https://localhost:7252"))
    .AddHttpMessageHandler<CustomAuthorizationMessageHandler>(); // 与命名客户端使用相同的处理器

3. 正确获取HttpClient

在Blazor WebAssembly中,通过依赖注入获取客户端,而非直接调用HttpClientFactory.CreateClient,确保服务容器正确解析所有依赖:

// 在组件或服务中通过构造函数注入
public class WeatherService
{
    private readonly IWeatherApi _weatherApi;

    public WeatherService(IWeatherApi weatherApi)
    {
        _weatherApi = weatherApi;
    }

    // 使用_weatherApi调用接口
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 02:24:50