Blazor WebAssembly注册IUserData服务后仍提示未注册异常如何解决?
问题根因
你犯了Blazor WebAssembly架构的典型认知错误:
- Blazor WebAssembly是前后端分离架构,分为Server端项目(运行在后端服务器,负责数据库操作、接口逻辑)和Client端项目(运行在用户浏览器中,仅处理前端逻辑),两个项目的依赖注入容器完全隔离
- 你将
IUserData、ISqlDataAccess这类数据库操作服务注册到了Server端的Startup.cs中,但报错的Users页面属于ChoresAppTheThird.Client(前端项目),前端的DI容器从未注册过这两个服务,必然会抛出找不到服务的异常 - 另外直接操作数据库的
SqlDataAccess逻辑本就不能在前端运行:浏览器环境没有数据库驱动,也不可能直接访问你的业务数据库,会存在严重的安全风险
解决方案
步骤1:Server端新增API接口
在Server项目中新增UsersController,封装IUserData调用逻辑,对外提供HTTP接口:
[ApiController] [Route("api/[controller]")] public class UsersController : ControllerBase { private readonly IUserData _userData; public UsersController(IUserData userData) { _userData = userData; } [HttpGet] public async Task<ActionResult<List<PersonModel>>> GetAllUsers() { var users = await _userData.GetPeople(); return Ok(users); } }
步骤2:修改Client端页面逻辑
删掉前端页面直接注入IUserData的逻辑,改为注入HttpClient调用后端接口:
@page "/users" @inject HttpClient Http @using DataAccessLibrary.Models <h3>Users</h3> @if (people == null) { <p><em>加载中...</em></p> } else { <table class="table table-striped"> <thead> <tr> <th>姓名</th> <th>邮箱</th> <th>手机号码</th> </tr> </thead> @foreach (PersonModel user in people) { <tr> <td> @user.Name </td> <td> @user.Email </td> <td> @user.PhoneNumber </td> </tr> } </table> } @code { private List<PersonModel> people; protected override async Task OnInitializedAsync() { people = await Http.GetFromJsonAsync<List<PersonModel>>("api/users"); } }
步骤3:确认Client端HttpClient注册
检查Client项目的Program.cs(不是Server的Startup.cs)是否已注册HttpClient,默认Blazor WebAssembly模板已自带该配置,缺失则手动添加:
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
步骤4:保留原有Server端服务注册
你之前在Server端Startup.cs里写的IUserData、ISqlDataAccess注册逻辑不用修改,保留下来给Controller调用即可。
额外说明
如果你不想写API、想要直接在页面中操作数据库,应该选用Blazor Server架构而非Blazor WebAssembly。Blazor Server的代码全量运行在服务器上,DI容器全局共享,直接注入数据库服务是可行的。
内容的提问来源于stack exchange,提问作者Isaac
相关产品推荐
相关产品推荐

