使用MudBlazor和FluentValidation实现开关字段联动触发验证
实现MudBlazor双Switch联动验证(至少一个开启)
方案一:使用DataAnnotations自定义验证属性
1. 创建自定义验证属性
这个属性会检查当前属性与指定的另一个属性是否至少有一个为true:
public class AtLeastOneTrueAttribute : ValidationAttribute { private readonly string _otherPropertyName; public AtLeastOneTrueAttribute(string otherPropertyName) { _otherPropertyName = otherPropertyName; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var otherProperty = validationContext.ObjectType.GetProperty(_otherPropertyName); if (otherProperty == null) { return new ValidationResult($"无法找到指定属性:{_otherPropertyName}"); } var otherValue = otherProperty.GetValue(validationContext.ObjectInstance); if (value is not bool currentBool || otherValue is not bool otherBool) { return new ValidationResult("验证的属性必须是布尔类型"); } if (!currentBool && !otherBool) { return new ValidationResult("至少需要开启一个开关"); } return ValidationResult.Success; } }
2. 给模型属性添加验证标记
在两个Switch绑定的模型属性上,互相引用对方作为验证关联属性:
public class SwitchFormModel { [AtLeastOneTrue(nameof(Switch2))] public bool Switch1 { get; set; } [AtLeastOneTrue(nameof(Switch1))] public bool Switch2 { get; set; } }
3. 组件中实现联动验证
在EditForm中,给每个MudSwitch的ValueChanged事件添加触发表单验证的逻辑,确保开关状态变化时重新执行验证:
<EditForm Model="@formModel" OnValidSubmit="@HandleSubmit" @ref="formRef"> <DataAnnotationsValidator /> <ValidationSummary /> <MudSwitch @bind-Value="formModel.Switch1" Label="开关1" ValueChanged="TriggerFullValidation" /> <ValidationMessage For="@(() => formModel.Switch1)" /> <MudSwitch @bind-Value="formModel.Switch2" Label="开关2" ValueChanged="TriggerFullValidation" /> <ValidationMessage For="@(() => formModel.Switch2)" /> <MudButton Type="ButtonType.Submit" Variant="Variant.Filled">提交</MudButton> </EditForm> @code { private SwitchFormModel formModel = new(); private EditForm? formRef; private void TriggerFullValidation() { formRef?.EditContext?.Validate(); } private void HandleSubmit() { // 执行表单提交逻辑 } }
方案二:使用FluentValidation(如果项目已集成)
1. 编写验证规则
创建验证器类,为两个属性添加组合验证规则:
public class SwitchFormModelValidator : AbstractValidator<SwitchFormModel> { public SwitchFormModelValidator() { RuleFor(m => m.Switch1) .Must((model, val) => val || model.Switch2) .WithMessage("至少需要开启一个开关"); RuleFor(m => m.Switch2) .Must((model, val) => val || model.Switch1) .WithMessage("至少需要开启一个开关"); } }
2. 组件中配置验证器并触发联动
将DataAnnotationsValidator替换为FluentValidationValidator,其余逻辑和方案一一致:
<EditForm Model="@formModel" OnValidSubmit="@HandleSubmit" @ref="formRef"> <FluentValidationValidator /> <ValidationSummary /> <MudSwitch @bind-Value="formModel.Switch1" Label="开关1" ValueChanged="TriggerFullValidation" /> <ValidationMessage For="@(() => formModel.Switch1)" /> <MudSwitch @bind-Value="formModel.Switch2" Label="开关2" ValueChanged="TriggerFullValidation" /> <ValidationMessage For="@(() => formModel.Switch2)" /> <MudButton Type="ButtonType.Submit" Variant="Variant.Filled">提交</MudButton> </EditForm>
核心逻辑说明
- 跨属性验证:不管用哪种方式,都需要确保验证规则同时检查两个开关的状态,而不是单独验证单个开关。
- 手动触发验证:通过
ValueChanged事件调用EditContext.Validate(),让表单在任意开关变更时重新执行所有验证规则,从而自动更新另一个开关的错误提示。
内容的提问来源于stack exchange,提问作者700z
相关产品推荐
相关产品推荐

