Blazor WASM托管项目依赖注入报错:无法解析SQLConnConfig的String服务
问题原因及修复方案
错误根源
- 客户端DI容器缺少SQLConnConfig注册:你在客户端
program.cs中注册了MyService,但MyService依赖SQLConnConfig,而客户端的DI容器中未注册SQLConnConfig。当客户端尝试创建MyService实例时,无法解析SQLConnConfig构造函数所需的string参数,因此抛出错误。 - 架构设计错误:Blazor WebAssembly客户端运行在浏览器沙箱环境中,不能直接使用
SqlConnection连接数据库,这违反了WASM的安全模型和架构规范,数据库操作必须放在服务端完成。 - 重复注册服务导致混淆:你同时在服务端
Startup.cs和客户端program.cs中注册了MyService,两个DI容器的服务注册冲突,进一步加剧了依赖解析问题。
修复步骤
1. 重构数据访问逻辑,将数据库操作移至服务端
在Server项目中创建负责数据库操作的服务,并通过API接口暴露给客户端:
服务端创建数据服务
// MyProject.Server/Services/MyServerService.cs public class MyServerService { private readonly SQLConnConfig _connConfig; public MyServerService(SQLConnConfig connConfig) { _connConfig = connConfig; } public List<Item> GetItems() { var items = new List<Item>(); using var connection = new SqlConnection(_connConfig.Value); connection.Open(); // 执行查询逻辑,示例: var command = new SqlCommand("SELECT Id, Name FROM Items", connection); using var reader = command.ExecuteReader(); while (reader.Read()) { items.Add(new Item { Id = reader.GetString(0), Name = reader.GetString(1) }); } return items; } }
服务端创建API控制器
// MyProject.Server/Controllers/ItemsController.cs [ApiController] [Route("api/[controller]")] public class ItemsController : ControllerBase { private readonly MyServerService _serverService; public ItemsController(MyServerService serverService) { _serverService = serverService; } [HttpGet] public IActionResult GetItems() { var items = _serverService.GetItems(); return Ok(items); } }
2. 修正服务端DI配置
更新MyProject.Server/Startup.cs,确保服务注册正确并启用API控制器:
public void ConfigureServices(IServiceCollection services) { // 注册SQL连接配置 var sqlConnConfig = new SQLConnConfig(Configuration.GetConnectionString("DefaultConnection")); services.AddSingleton<SQLConnConfig>(sqlConnConfig); // 注册服务端数据服务 services.AddSingleton<MyServerService>(); services.AddServerSideBlazor(x => x.DetailedErrors = true); // 启用API控制器支持 services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // ... 其他中间件配置 app.UseRouting(); // 添加API端点路由 app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); }); }
3. 修正客户端DI配置与服务逻辑
客户端不再直接操作数据库,改为通过HttpClient调用服务端API:
客户端创建API调用服务
// MyProject.Client/Services/MyClientService.cs public class MyClientService { private readonly HttpClient _httpClient; public MyClientService(HttpClient httpClient) { _httpClient = httpClient; } public async Task<List<Item>> GetItemsAsync() { return await _httpClient.GetFromJsonAsync<List<Item>>("api/items"); } }
更新客户端program.cs
// 移除原有的MyService注册,添加HttpClient和客户端服务 builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.AddScoped<MyClientService>();
4. 更新客户端组件使用逻辑
修改index.razor,注入客户端服务并调用API:
@inject MyClientService ClientService @using MyProject.Client.Data @if (items == null) { <p>加载中...</p> } else { <ul> @foreach (var item in items) { <li>@item.Name(ID:@item.Id)</li> } </ul> } @code { private List<Item> items; protected override async Task OnInitializedAsync() { items = await ClientService.GetItemsAsync(); } }
最终注意事项
- 移除客户端项目中与直接数据库操作相关的代码(如
MyService中的SqlConnection逻辑),避免不必要的依赖。 - 确保服务端的连接字符串在
appsettings.json中正确配置,且数据库服务正常运行。
内容的提问来源于stack exchange,提问作者Sarahrb
相关产品推荐
相关产品推荐

