如何将ModelState校验错误传入MudBlazor ValidationSummary显示
实现方法
核心逻辑是把后端返回的校验错误写入Blazor表单的ValidationMessageStore,MudBlazor的ValidationSummary和输入框控件会自动读取这个存储里的错误信息渲染,不需要额外维护单独的错误字符串数组。
具体修改步骤
- 替换直接绑定Model的EditForm写法,持有EditContext实例,配套初始化验证消息存储
- 调整提交逻辑:请求发送前清空历史错误,仅在请求失败时读取后端返回的错误字典
- 遍历错误字典,将字段和对应错误写入验证存储,通知UI刷新验证状态
修改后的完整代码
@page "/marketingeventcreate" @inject HttpClient Http @inject NavigationManager NavManager @using System.Text.RegularExpressions @using System.ComponentModel.DataAnnotations @using OnlinePlatform.Support.Domain.Entities @using OnlinePlatform.Support.Domain.Dtos <EditForm EditContext="@editContext" OnValidSubmit="OnValidSubmit"> <DataAnnotationsValidator/> <MudGrid> <MudItem xs="12" sm="7"> <MudCard> <MudCardContent> <MudTextField Label="Event Name" HelperText="" @bind-Value="model.Name" For="@(() => model.Name)"/> <MudTextField Label="Remark" Class="mt-3" @bind-Value="model.Remark" For="@(() => model.Remark)"/> <MudTextField Label="Event Date" HelperText="" Class="mt-3" InputType="InputType.Date" Mask="@(new DateMask("dd.MM.yyyy"))" DateFormat="dd.MM.yyyy" @bind-Value="model.EventDate" For="@(() => model.EventDate)" /> <MudTextField Label="Venue" HelperText="" Class="mt-3" @bind-Value="model.Venue" For="@(() => model.Venue)" /> <MudTextField Label="State" HelperText="" Class="mt-3" @bind-Value="model.State" For="@(() => model.State)" /> <MudTextField Label="Start Time" HelperText="i.e. 2000" Class="mt-3" @bind-Value="model.StartTime" For="@(() => model.StartTime)" /> <MudTextField Label="End Time" HelperText="i.e. 2100" Class="mt-3" @bind-Value="model.EndTime" For="@(() => model.EndTime)" /> </MudCardContent> <MudCardActions> <MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="Color.Primary" Class="ml-auto">Submit</MudButton> </MudCardActions> </MudCard> </MudItem> <MudItem xs="12" sm="5"> <MudPaper Class="pa-4 mud-height-full"> <MudText Typo="Typo.subtitle2">Validation Summary</MudText> @if (success) { <MudText Color="Color.Success">Success</MudText> } else { <MudText Color="@Color.Error"> <ValidationSummary /> </MudText> } </MudPaper> </MudItem> </MudGrid> </EditForm> @code { MarketingEvent model = new MarketingEvent(); EditContext editContext; ValidationMessageStore validationMessageStore; bool success; protected override void OnInitialized() { editContext = new EditContext(model); validationMessageStore = new ValidationMessageStore(editContext); } private async Task OnValidSubmit(EditContext context) { success = false; // 清空上一次提交的历史错误 validationMessageStore.Clear(); var mydate = new DateTime(model.EventDate.Year, model.EventDate.Month, model.EventDate.Day); var request = new CreateMarketingEventRequest(model.Name, model.Remark, mydate, model.Venue, model.State, model.StartTime?.ToString(), model.EndTime?.ToString()); try { var response = await Http.PostAsJsonAsync("api/marketingevent", request); if (response.IsSuccessStatusCode) { if (response.StatusCode == System.Net.HttpStatusCode.Created) { success = true; NavManager.NavigateTo("/"); return; } } else { // 仅校验失败时读取错误字典,避免成功响应反序列化报错 var serverErrors = await response.Content .ReadFromJsonAsync<Dictionary<string, List<string>>>(); if (serverErrors != null) { foreach (var errorItem in serverErrors) { // 如果后端返回的是小驼峰字段名,用下面这行转成和C#属性匹配的大驼峰 string fieldName = char.ToUpperInvariant(errorItem.Key[0]) + errorItem.Key.Substring(1); // 如果后端字段名和前端模型属性名大小写完全一致,直接用 errorItem.Key 即可 // string fieldName = errorItem.Key; FieldIdentifier field = editContext.Field(fieldName); validationMessageStore.Add(field, errorItem.Value); } // 通知表单刷新验证状态 editContext.NotifyValidationStateChanged(); } } } catch (Exception ex) { // 网络异常等非业务错误添加全局提示 validationMessageStore.Add(editContext.Field(string.Empty), new[] { $"提交失败:{ex.Message}" }); editContext.NotifyValidationStateChanged(); } } }
注意事项
- 该方案不仅能让
ValidationSummary显示所有后端错误,对应字段的MudTextField也会自动标红、在输入框下方显示专属错误提示,不需要额外绑定错误参数 - 原有前端
DataAnnotations校验逻辑完全不受影响,前后端校验错误会合并展示 - 不对应具体字段的全局错误,给
editContext.Field传空字符串即可,会显示在汇总区域顶部
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

