如何为Blazor ValidationMessage添加动态自定义文本?
Blazor动态验证消息实现方案
方案一:自定义验证属性+手动替换消息
默认DataAnnotation属性无法直接绑定动态变量,你可以自定义支持占位符的验证属性,再在组件中替换占位符内容:
- 自定义StringLength属性:
public class DynamicStringLengthAttribute : StringLengthAttribute { public DynamicStringLengthAttribute(int maximumLength) : base(maximumLength) { ErrorMessage = "{FieldName}必须在3到100字符之间。"; MinimumLength = 3; } }
- 在SearchFields类中使用自定义属性:
private class SearchFields { [DynamicStringLength(100)] public string? FirstField { get; set; } }
- 组件中手动渲染验证消息并替换字段名:
<div class="row"> <label class="col-12 col-sm-4 col-form-label">@FirstFieldLabel:</label> <div class="col-12 col-sm-8 ps-2"> <InputText id="FirstField" class="form-control form-control-sm" @bind-Value="@SearchFields.FirstField" /> @* 手动获取验证消息并替换占位符 *@ @if (EditContext.GetValidationMessages(() => SearchFields.FirstField).Any()) { foreach (var message in EditContext.GetValidationMessages(() => SearchFields.FirstField)) { <div class="text-danger">@message.Replace("{FieldName}", FirstFieldLabel)</div> } } </div> </div> @code { private EditContext? EditContext { get; set; } private string? FirstFieldLabel { get; set; } private SearchFields SearchFields = new(); protected override async Task OnInitializedAsync() { FirstFieldLabel = await _dbLayer.GetFirstFieldLabel(); EditContext = new EditContext(SearchFields); } }
方案二:使用FluentValidation(更灵活)
FluentValidation支持动态构建错误消息,适合复杂场景:
- 安装
FluentValidation.Blazor包 - 创建带动态字段名的验证器:
public class SearchFieldsValidator : AbstractValidator<SearchFields> { private readonly string _fieldLabel; public SearchFieldsValidator(string fieldLabel) { _fieldLabel = fieldLabel; RuleFor(x => x.FirstField) .Length(3, 100) .WithMessage($"{_fieldLabel}必须在3到100字符之间。"); } }
- 组件中注册验证器并使用:
@using FluentValidation.Blazor <div class="row"> <label class="col-12 col-sm-4 col-form-label">@FirstFieldLabel:</label> <div class="col-12 col-sm-8 ps-2"> <InputText id="FirstField" class="form-control form-control-sm" @bind-Value="@SearchFields.FirstField" /> <ValidationMessage For="() => SearchFields.FirstField" /> </div> </div> @code { private EditContext? EditContext { get; set; } private string? FirstFieldLabel { get; set; } private SearchFields SearchFields = new(); protected override async Task OnInitializedAsync() { FirstFieldLabel = await _dbLayer.GetFirstFieldLabel(); EditContext = new EditContext(SearchFields); // 注册带动态字段名的验证器 EditContext.AddFluentValidation(new SearchFieldsValidator(FirstFieldLabel)); } }
方案三:直接修改EditContext验证消息(简单粗暴)
如果不想改动验证属性,可在获取动态字段名后手动替换验证消息:
<div class="row"> <label class="col-12 col-sm-4 col-form-label">@FirstFieldLabel:</label> <div class="col-12 col-sm-8 ps-2"> <InputText id="FirstField" class="form-control form-control-sm" @bind-Value="@SearchFields.FirstField" /> <ValidationMessage For="() => SearchFields.FirstField" /> </div> </div> @code { private EditContext? EditContext { get; set; } private string? FirstFieldLabel { get; set; } private SearchFields SearchFields = new(); protected override async Task OnInitializedAsync() { FirstFieldLabel = await _dbLayer.GetFirstFieldLabel(); EditContext = new EditContext(SearchFields); // 监听验证状态变化,替换消息 EditContext.OnValidationStateChanged += (sender, args) => { var fieldIdentifier = FieldIdentifier.Create(() => SearchFields.FirstField); var messages = EditContext.GetValidationMessages(fieldIdentifier).ToList(); if (messages.Any()) { EditContext.ClearValidationMessages(fieldIdentifier); EditContext.AddValidationMessage(fieldIdentifier, $"{FirstFieldLabel}必须在3到100字符之间。"); } }; } }
内容的提问来源于stack exchange,提问作者PKD
相关产品推荐
相关产品推荐

