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

Blazor WebAssembly已注册服务仍提示‘无注册服务’问题排查

Blazor WebAssembly 服务注入偶发失败问题解决

问题场景

我有一个采用WebAssembly渲染模式的Blazor应用。客户端Demo页面代码如下:

@page "/demo"
@page "/{lang}/demo"
@inject IDemoService DemoService
@inject ICsvImportService CsvImportService
@inject ILanguageService LanguageService
...
@code {
    [Parameter]
    public required string Lang { get; set; }

    protected override void OnParametersSet()
    {
        text =  LanguageService.GetLocalizedStrings("AppName.Client.Localization.Strings.Demo.csv", Lang ?? Constants.SupportedLanguages[0]);
    }
...
}

服务在客户端Program.cs中的注册方式:

string apiUrl = "https://localhost:7254"; // TODO move to appsettings.json
string apiVersion = "/api/v1";

builder.Services.AddRefitClient<IDemoService>()
    .ConfigureHttpClient(c => c.BaseAddress = new Uri($"{apiUrl}{apiVersion}"));

builder.Services.AddScoped<IEmbeddedCsvService, EmbeddedCsvService>();
builder.Services.AddScoped<ILanguageService, LanguageService>();
builder.Services.AddScoped<ICsvImportService, CsvImportService>();

偶发出现以下错误(比如手动修改URL语言代码时):

InvalidOperationException: Cannot provide a value for property 'DemoService' on type 'AppName.Client.Features.Calculation.Demo.Page.Demo'. There is no registered service of type 'AppName.Client.Features.Calculation.Demo.Service.IDemoService'.

奇怪的是页面加载后调用API时服务又能正常工作,后续发现即使不修改语言版本、非Refit相关服务也会出现此问题。

解决方法

1. 修复路由参数的必填约束与默认值

Lang参数标记为required,但访问/demo路由时无参数传入,会导致组件初始化阶段参数绑定异常,间接引发服务注入问题。修改参数定义:

[Parameter]
public string Lang { get; set; } = Constants.SupportedLanguages[0];

同时简化OnParametersSet逻辑:

protected override void OnParametersSet()
{
    text = LanguageService.GetLocalizedStrings("AppName.Client.Localization.Strings.Demo.csv", Lang);
}

2. 调整服务注册顺序

将Refit客户端注册放在自定义Scoped服务之前,避免边缘场景下的依赖解析时机问题:

// 优先注册Refit客户端
builder.Services.AddRefitClient<IDemoService>()
    .ConfigureHttpClient(c => c.BaseAddress = new Uri($"{apiUrl}{apiVersion}"));

// 再注册其他自定义服务
builder.Services.AddScoped<IEmbeddedCsvService, EmbeddedCsvService>();
builder.Services.AddScoped<ILanguageService, LanguageService>();
builder.Services.AddScoped<ICsvImportService, CsvImportService>();

3. 改用构造函数注入替代属性注入

属性注入在Blazor组件初始化的某些阶段可能存在解析延迟,构造函数注入能确保服务在组件实例化时就被正确解析:

@page "/demo"
@page "/{lang}/demo"

@code {
    private readonly IDemoService _demoService;
    private readonly ICsvImportService _csvImportService;
    private readonly ILanguageService _languageService;
    private string text;

    [Parameter]
    public string Lang { get; set; } = Constants.SupportedLanguages[0];

    // 构造函数注入所有依赖服务
    public Demo(IDemoService demoService, ICsvImportService csvImportService, ILanguageService languageService)
    {
        _demoService = demoService;
        _csvImportService = csvImportService;
        _languageService = languageService;
    }

    protected override void OnParametersSet()
    {
        text = _languageService.GetLocalizedStrings("AppName.Client.Localization.Strings.Demo.csv", Lang);
    }
...
}

4. 禁用页面的预渲染(若启用)

如果应用开启了预渲染(如Static Web Apps预渲染或服务器端预渲染),客户端服务在预渲染阶段无法被解析,会触发异常。给页面添加属性禁用预渲染:

@attribute [RenderModeWebAssembly]

5. 清理缓存并重新构建

Blazor WebAssembly的缓存可能导致旧代码未更新,执行以下操作:

  • 强制刷新浏览器(Ctrl+Shift+R)
  • 删除客户端项目的bin和obj目录,重新构建项目

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 11:28:28