使用Blazor ASP.NET的EditForm验证避免数据库重复项目
实现EditForm内项目名称唯一性验证(无需jQuery)
完全可以通过Blazor的EditForm实现,不需要依赖jQuery这类第三方库。Blazor自带的验证体系支持结合数据注解和异步逻辑来完成数据库唯一性检查,下面是两种常用的实现方案:
方案一:自定义异步验证属性(推荐,贴合数据注解体系)
这种方式把唯一性验证逻辑封装成数据注解属性,和你已经用的[Required]、[StringLength]统一管理,代码更整洁。
1. 编写自定义验证属性
创建一个继承自ValidationAttribute的类,实现异步验证逻辑来查询数据库:
public class UniqueProjectNameAttribute : ValidationAttribute { protected override async Task<ValidationResult> IsValidAsync(object value, ValidationContext validationContext) { // 从依赖注入中获取数据库操作服务 var projectRepo = validationContext.GetService(typeof(IProjectRepository)) as IProjectRepository; if (projectRepo == null) { return new ValidationResult("无法完成名称唯一性验证"); } var projectName = value as string; if (string.IsNullOrWhiteSpace(projectName)) { // 空值的验证交给[Required]处理 return ValidationResult.Success; } // 查询数据库检查名称是否已存在 if (await projectRepo.IsNameExistsAsync(projectName)) { return new ValidationResult("该项目名称已存在,请更换"); } return ValidationResult.Success; } }
2. 给模型属性添加验证属性
在你的项目模型中,把自定义属性加到名称字段上:
public class Project { [Required(ErrorMessage = "项目名称不能为空")] [StringLength(50, ErrorMessage = "项目名称不能超过50个字符")] [UniqueProjectName] // 新增唯一性验证 public string Name { get; set; } // 其他项目属性... }
3. 配置EditForm验证组件
在Razor页面的EditForm中,保留DataAnnotationsValidator来启用数据注解验证,同时添加验证提示组件:
<EditForm Model="@newProject" OnValidSubmit="@HandleCreateProject"> <DataAnnotationsValidator /> <ValidationSummary /> <div class="form-group"> <label>项目名称:</label> <InputText @bind-Value="@newProject.Name" class="form-control" /> <ValidationMessage For="@(() => newProject.Name)" /> </div> <button type="submit" class="btn btn-primary">创建项目</button> </EditForm> @code { private Project newProject = new(); // 注入数据库操作服务 [Inject] private IProjectRepository ProjectRepo { get; set; } private async Task HandleCreateProject() { // 执行项目创建逻辑 await ProjectRepo.CreateProjectAsync(newProject); // 重置表单 newProject = new(); } }
方案二:手动触发异步验证(灵活可控)
如果你需要更灵活的验证时机(比如输入时实时检查),可以手动操作EditContext来添加验证消息:
<EditForm EditContext="@editContext" OnValidSubmit="@HandleCreateProject"> <DataAnnotationsValidator /> <ValidationSummary /> <div class="form-group"> <label>项目名称:</label> <InputText @bind-Value="@newProject.Name" class="form-control" @oninput="@CheckNameUnique" /> <ValidationMessage For="@(() => newProject.Name)" /> </div> <button type="submit" class="btn btn-primary">创建项目</button> </EditForm> @code { private Project newProject = new(); private EditContext editContext; [Inject] private IProjectRepository ProjectRepo { get; set; } protected override void OnInitialized() { editContext = new EditContext(newProject); } private async Task CheckNameUnique() { var nameField = FieldIdentifier.Create(() => newProject.Name); // 清除之前的名称验证消息 editContext.ClearValidationMessages(nameField); if (!string.IsNullOrWhiteSpace(newProject.Name)) { if (await ProjectRepo.IsNameExistsAsync(newProject.Name)) { editContext.AddValidationMessage(nameField, "该项目名称已存在,请更换"); } } // 通知验证状态变更,更新UI editContext.NotifyValidationStateChanged(); } private async Task HandleCreateProject() { // 提交前再次验证,避免并发创建同名项目 if (await ProjectRepo.IsNameExistsAsync(newProject.Name)) { var nameField = FieldIdentifier.Create(() => newProject.Name); editContext.AddValidationMessage(nameField, "该项目名称已存在,请更换"); return; } await ProjectRepo.CreateProjectAsync(newProject); newProject = new(); editContext = new EditContext(newProject); } }
注意事项
- 无论用哪种方案,都要处理并发问题:提交前务必再次检查名称唯一性,防止两个用户同时创建同名项目。
- 为数据库的项目名字段添加唯一索引,从底层避免重复数据,同时提升查询性能。
内容的提问来源于stack exchange,提问作者Ben Pugh
相关产品推荐
相关产品推荐

