Blazor是否具备类似ASP.NET Web Forms的ValidationGroups功能实现同模型多表单验证
Blazor 没有内置与 Web Forms ValidationGroup 完全同名的 API,但有两种成熟方案可以实现完全一致的分组校验效果,适配你描述的单页多表单共用模型的场景。
方案1:使用独立
EditForm 隔离校验(最推荐,零额外自定义代码) Blazor 的 EditForm 本身就是天然的校验隔离单元,就算多个 EditForm 共用同一个模型实例,每个表单只会校验自身内部包含的输入控件,完全不会互相干扰,和你需要的分组效果完全匹配。
示例代码如下:
共用模型定义
public class UserAccountModel { [Required(ErrorMessage = "邮箱不能为空")] [EmailAddress(ErrorMessage = "邮箱格式不合法")] public string Email { get; set; } [Required(ErrorMessage = "密码不能为空")] public string Password { get; set; } // 仅注册表单需要的字段 [Required(ErrorMessage = "确认密码不能为空")] [Compare(nameof(Password), ErrorMessage = "两次输入密码不一致")] public string ConfirmPassword { get; set; } }
页面实现
@page "/account" @using System.ComponentModel.DataAnnotations <!-- 登录表单 --> <EditForm Model="@AccountModel" OnValidSubmit="HandleLogin"> <DataAnnotationsValidator /> <ValidationSummary /> <InputText @bind-Value="AccountModel.Email" placeholder="请输入邮箱" /> <ValidationMessage For="@(() => AccountModel.Email)" /> <InputText type="password" @bind-Value="AccountModel.Password" placeholder="请输入密码" /> <ValidationMessage For="@(() => AccountModel.Password)" /> <button type="submit" class="btn btn-primary">登录</button> </EditForm> <hr /> <!-- 新建账户表单 --> <EditForm Model="@AccountModel" OnValidSubmit="HandleRegister"> <DataAnnotationsValidator /> <ValidationSummary /> <InputText @bind-Value="AccountModel.Email" placeholder="请输入邮箱" /> <ValidationMessage For="@(() => AccountModel.Email)" /> <InputText type="password" @bind-Value="AccountModel.Password" placeholder="请设置密码" /> <ValidationMessage For="@(() => AccountModel.Password)" /> <InputText type="password" @bind-Value="AccountModel.ConfirmPassword" placeholder="请确认密码" /> <ValidationMessage For="@(() => AccountModel.ConfirmPassword)" /> <button type="submit" class="btn btn-success">注册账户</button> </EditForm> @code { // 两个表单共用同一个模型实例 private UserAccountModel AccountModel = new(); private void HandleLogin() { // 仅登录表单内字段校验通过后才会执行此处逻辑 // 写入登录业务代码即可 } private void HandleRegister() { // 仅注册表单内字段校验通过后才会执行此处逻辑 // 写入注册业务代码即可 } }
此方案下点击登录按钮只会校验登录表单内的邮箱、密码两个字段,完全不会触发确认密码的校验规则,和Web Forms ValidationGroup的使用效果完全一致,无需额外封装。
方案2:自定义校验分组(适配同个EditForm内需要多分组的场景)
如果你确实需要把两个提交按钮放在同一个 EditForm 内部,可以自定义校验分组属性实现能力:
自定义分组校验属性
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] public class ValidationGroupAttribute : ValidationAttribute { public string GroupName { get; } public ValidationGroupAttribute(string groupName) { GroupName = groupName; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { if (validationContext.Items.TryGetValue("ActiveValidationGroup", out var activeGroup) && activeGroup?.ToString() == GroupName) { var validationResults = new List<ValidationResult>(); var groupProperties = validationContext.ObjectType.GetProperties() .Where(p => p.GetCustomAttributes(typeof(ValidationGroupAttribute), true) .Any(a => ((ValidationGroupAttribute)a).GroupName == GroupName)); foreach (var prop in groupProperties) { Validator.TryValidateProperty( prop.GetValue(validationContext.ObjectInstance), new ValidationContext(validationContext.ObjectInstance) { MemberName = prop.Name }, validationResults ); } if (validationResults.Any()) { return new ValidationResult(string.Join("\n", validationResults.Select(r => r.ErrorMessage))); } } return ValidationResult.Success; } }
使用时在模型属性上标注所属分组,提交时传入当前激活的分组名即可触发对应分组的校验。
内容的提问来源于stack exchange,提问作者user13714356
相关产品推荐
相关产品推荐

