You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Web App如何按模型Display Order属性排序验证错误消息

Blazor中让ValidationSummary按模型Display(Order)排序错误消息

问题场景

我在Blazor Web App组件中使用EditForm和ValidationSummary,功能正常但错误消息顺序不符合预期:自定义验证的错误会排在数据注解(比如[Required])的错误前面。比如留空FirstName且输入2个字符的MiddleName时,错误顺序是:

'Middle Name' must be at least 5 characters
'First Name' is required

但我希望按照模型中[Display(Order = XX)]属性定义的顺序展示错误消息(FirstName的Order=2,应该排在MiddleName的Order=3前面)。

模型代码:

public class ContactModel
{
  [Display(Order = 1)]
  public int ContactID { get; set; }
  [Required]
  [Display(Order = 2)]
  public string FirstName { get; set; }
  [Display(Order = 3)]
  public string MiddleName { get; set; }
  [Required]
  [Display(Order = 4)]
  public string LastName { get; set; }
}

自定义验证代码:

if (!String.IsNullOrEmpty(_model.MiddleName) && _model.MiddleName.Length < 5)
{
    messageStore?.Add(() => _model.MiddleName, "Middle name must be at least 5 characters.");
}
_editContext.NotifyValidationStateChanged();

解决方案

默认的ValidationSummary不支持按模型属性顺序排序,需要自定义一个排序后的验证摘要组件:

1. 创建自定义SortedValidationSummary组件

新建SortedValidationSummary.razor文件,代码如下:

@inject EditContext EditContext
@if (EditContext?.GetValidationMessages().Any() == true)
{
    <div class="validation-summary-errors" role="alert">
        <ul>
            @foreach (var message in GetSortedValidationMessages())
            {
                <li>@message</li>
            }
        </ul>
    </div>
}

@code {
    private IEnumerable<string> GetSortedValidationMessages()
    {
        // 关联验证消息与对应字段
        var fieldMessages = new List<(string Message, int Order)>();
        var modelType = typeof(ContactModel);

        foreach (var fieldIdentifier in EditContext.GetFieldsWithValidationMessages())
        {
            // 获取属性的DisplayOrder
            var property = modelType.GetProperty(fieldIdentifier.FieldName);
            var displayOrder = property?.GetCustomAttributes(typeof(DisplayAttribute), false)
                .Cast<DisplayAttribute>()
                .FirstOrDefault()?.Order ?? int.MaxValue;

            // 收集该字段的所有错误消息
            foreach (var msg in EditContext.GetValidationMessages(fieldIdentifier))
            {
                fieldMessages.Add((msg, displayOrder));
            }
        }

        // 按DisplayOrder排序后返回消息
        return fieldMessages.OrderBy(item => item.Order).Select(item => item.Message);
    }
}

2. 替换原ValidationSummary

在你的Blazor组件中,把原来的<ValidationSummary />替换为自定义组件:

<EditForm Model="@_model" OnValidSubmit="@HandleValidSubmit">
    <!-- 表单输入控件 -->
    <SortedValidationSummary />
    <button type="submit">提交</button>
</EditForm>

3. 通用化扩展(可选)

如果需要让组件支持任意模型,可以改成泛型组件:

@typeparam TModel
@inject EditContext EditContext
@if (EditContext?.GetValidationMessages().Any() == true)
{
    <div class="validation-summary-errors" role="alert">
        <ul>
            @foreach (var message in GetSortedValidationMessages())
            {
                <li>@message</li>
            }
        </ul>
    </div>
}

@code {
    private IEnumerable<string> GetSortedValidationMessages()
    {
        var fieldMessages = new List<(string Message, int Order)>();
        var modelType = typeof(TModel);

        foreach (var fieldIdentifier in EditContext.GetFieldsWithValidationMessages())
        {
            var property = modelType.GetProperty(fieldIdentifier.FieldName);
            var displayOrder = property?.GetCustomAttributes(typeof(DisplayAttribute), false)
                .Cast<DisplayAttribute>()
                .FirstOrDefault()?.Order ?? int.MaxValue;

            foreach (var msg in EditContext.GetValidationMessages(fieldIdentifier))
            {
                fieldMessages.Add((msg, displayOrder));
            }
        }

        return fieldMessages.OrderBy(item => item.Order).Select(item => item.Message);
    }
}

使用时指定模型类型:

<SortedValidationSummary TModel="ContactModel" />

这样修改后,错误消息就会严格按照模型中[Display(Order)]定义的顺序展示。

内容的提问来源于stack exchange,提问作者FirstByte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 07:53:16