如何使用FluentValidation实现条件验证?自定义关联属性验证的异常问题求助
我来帮你搞定这两个问题,都是FluentValidation结合Blazor(从你用到的ValidationSummary组件判断)开发里常见的小坑,咱们一步一步来解决:
问题1:验证消息未显示在pos.Preis属性对应的输入框上
你当前的代码是针对整个pos对象做自定义验证,虽然在AddFailure里指定了属性名,但这种方式没有让FluentValidation明确把错误和Preis属性绑定起来。更好的做法是直接针对Preis字段创建规则,结合When条件关联Menge的数值,这样错误消息会自动关联到对应的属性输入框:
RuleFor(pos => pos.Preis) // 当数量小于10000时,价格最多2位小数 .Must((pos, preis) => MathExtensions.GetDecimalPlaces(preis) <= 2) .When(pos => pos.Menge < 10000) .WithMessage("Bei Mengen unter 10000 darf der Preis maximal 2 Nachkommastellen haben.") // 当数量大于等于10000时,价格最多4位小数 .Must((pos, preis) => MathExtensions.GetDecimalPlaces(preis) <= 4) .When(pos => pos.Menge >= 10000) .WithMessage("Der Preis darf maximal 4 Nachkommastellen haben.");
这种写法更符合FluentValidation的设计逻辑,每个规则都明确指向Preis属性,错误会直接显示在该属性的输入控件旁边,同时也会出现在ValidationSummary里。
问题2:修改属性时不自动触发验证
Blazor的EditForm默认验证模式是OnSubmit,也就是只有点击提交按钮时才会触发验证。要实现实时验证(修改属性值时就触发),你需要调整验证触发模式:
方法1:使用.NET 6+的ValidationMode参数
如果你的项目是.NET 6及以上版本,可以直接给EditForm设置ValidationMode为OnChange(值变更时验证)或者OnInput(输入时实时验证):
<EditForm Model="@yourModel" OnValidSubmit="HandleValidSubmit" ValidationMode="ValidationMode.OnChange"> <DataAnnotationsValidator /> <!-- Preis输入框及对应验证消息 --> <InputNumber @bind-Value="yourModel.Preis" /> <ValidationMessage For="@(() => yourModel.Preis)" /> <!-- Menge输入框及对应验证消息 --> <InputNumber @bind-Value="yourModel.Menge" /> <ValidationMessage For="@(() => yourModel.Menge)" /> <ValidationSummary /> <button type="submit">提交</button> </EditForm>
方法2:手动触发验证(兼容旧版本)
如果是.NET 5或更早版本,可以通过EditContext手动在输入控件的变更事件中触发验证:
首先在组件里声明EditContext:
@code { private EditContext? _editContext; private YourModel yourModel = new YourModel(); protected override void OnInitialized() { _editContext = new EditContext(yourModel); base.OnInitialized(); } }
然后在输入控件上添加@onchange事件:
<EditForm EditContext="@_editContext" OnValidSubmit="HandleValidSubmit"> <DataAnnotationsValidator /> <InputNumber @bind-Value="yourModel.Preis" @onchange="() => _editContext.Validate()" /> <ValidationMessage For="@(() => yourModel.Preis)" /> <InputNumber @bind-Value="yourModel.Menge" @onchange="() => _editContext.Validate()" /> <ValidationMessage For="@(() => yourModel.Menge)" /> <ValidationSummary /> <button type="submit">提交</button> </EditForm>
这样修改Preis或者Menge的值时,都会立刻触发验证,错误消息会实时更新。
额外注意
确保你已经正确注册了FluentValidation服务,比如在Program.cs里添加:
builder.Services.AddFluentValidationAutoValidation(); builder.Services.AddFluentValidationClientsideAdapters(); // 注册你的实体验证器 builder.Services.AddScoped<IValidator<YourModel>, YourModelValidator>();
内容的提问来源于stack exchange,提问作者Marvin Klein

