Blazor数据注解验证中无法从ValidationContext获取EFCore上下文
解决Blazor数据注解验证中注入EFCore Context的问题
核心问题分析
Blazor默认的ValidationContext并未关联应用的DI服务提供者,导致自定义ValidationAttribute无法直接获取EFCore Context等依赖服务,这是你遇到各类报错的根本原因。
步骤1:确认服务注册正确性
首先确保IMyContext及实现类已在Program.cs中正确注册:
// 注册DbContext builder.Services.AddDbContext<MyContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); // 注册接口到实现的映射 builder.Services.AddScoped<IMyContext>(sp => sp.GetRequiredService<MyContext>());
步骤2:自定义ValidationContext并传入服务提供者
在Blazor组件中,手动创建关联DI容器的ValidationContext,替代默认的验证逻辑:
- 组件中注入
IServiceProvider:
[Inject] private IServiceProvider ServiceProvider { get; set; }
- 自定义提交处理方法,手动执行验证:
private async Task HandleSubmit() { var validationContext = new ValidationContext(YourModelInstance) { ServiceProvider = ServiceProvider }; var validationResults = new List<ValidationResult>(); bool isValid = Validator.TryValidateObject( YourModelInstance, validationContext, validationResults, validateAllProperties: true ); if (isValid) { // 执行提交逻辑,比如保存到数据库 await using var dbContext = ServiceProvider.GetRequiredService<IMyContext>(); dbContext.YourEntities.Add(YourModelInstance); await dbContext.SaveChangesAsync(); } else { // 将验证错误同步到EditContext,更新UI状态 foreach (var result in validationResults) { foreach (var memberName in result.MemberNames) { EditContext.SetFieldCssClass( FieldIdentifier.Create(YourModelInstance, memberName), "invalid" ); } } } }
修正后的自定义ValidationAttribute
此时你的MyEntityExistsAttribute可以保持最初的实现,因为ValidationContext已能正确获取DI服务:
public class MyEntityExistsAttribute : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { if (value is not int id) { return new ValidationResult("ID必须是数字"); } var dbContext = validationContext.GetRequiredService<IMyContext>(); return dbContext.MyEntity.Any(s => s.Id == id) ? ValidationResult.Success : new ValidationResult("该ID不存在"); } }
错误原因解释
- No service for type 'IMyContext' registered:要么是服务未在DI容器中注册,要么是默认
ValidationContext的ServiceProvider为空,无法获取服务。 - No service for type 'IServiceScopeFactory' registered:默认
ValidationContext无有效ServiceProvider,调用CreateScope时无法找到依赖的IServiceScopeFactory服务。 - context为null:同样是因为
ValidationContext的ServiceProvider为空,GetService返回null。
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

