前端开发
在 Blazor 中构建表单、校验输入并响应交互(含…
当需要在 Blazor 中添加表单、搜索框、筛选面板、内联编辑、数据录入、文件上传、校验与提交处理时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
在 Blazor 中构建表单、校验输入并通用
解决思路
- 先阅读项目的 AGENTS.md,确认 Interactivity Mode(None/Server/WebAssembly/Auto)与 Interactivity Scope(Global/Per-page),据此选择表单模式:None 用 EditForm + FormName + [SupplyParameterFromForm],Server 用 EditForm + @bind-Value,WebAssembly 同 Server 但需服务端数据的校验器要调用 API,Auto 需代码同时兼容浏览器与服务端。
- EditForm 必须且只能设置 Model 或 EditContext 之一,不能同时使用。
- 默认使用基于 Model 的写法:<EditForm Model="Employee" OnValidSubmit="HandleSubmit" FormName="employee">,内部放 <DataAnnotationsValidator />、<ValidationSummary />、<InputText @bind-Value="Employee!.Name" /> 与 <ValidationMessage For="() => Employee!.Name" />,并在 @code 中用 [SupplyParameterFromForm] private EmployeeModel? Employee { get; set; } 与 protected override void OnInitialized() => Employee ??= new();。
- 需要程序化字段跟踪、动态校验规则或手动调用 EditContext.Validate() 时,改用基于 EditContext 的写法:在 OnInitialized 中 new EditContext(model),并设置 <EditForm EditContext="editContext" ...>。
- 按场景选择提交处理器:OnValidSubmit 用于校验通过的标准表单;OnInvalidSubmit 用于需要自定义处理无效状态;OnSubmit 用于手动调用 EditContext.Validate()。OnSubmit 不能与 OnValidSubmit/OnInvalidSubmit 同时使用。
- 使用内置输入组件并通过 @bind-Value 绑定:InputText(string)、InputTextArea(string)、InputNumber<T>(int/double/decimal)、InputDate<T>(DateTime/DateOnly/DateTimeOffset)、InputCheckbox(bool)、InputSelect<T>(string/枚举/数值)、InputRadioGroup<T>(包裹 InputRadio<T> 子项)、InputFile(IBrowserFile,仅交互模式)。始终用 <label> 包裹文本或使用 id/for 保证可访问性。
- InputSelect 绑定枚举时,先放一个空 <option value="">-- Select --</option>,再用 @foreach (var value in Enum.GetValues<OrderStatus>()) 渲染 <option value="@value">@value</option>。
- InputRadioGroup 绑定枚举时,用 @foreach 遍历 Enum.GetValues<Priority>(),每个选项用 <label><InputRadio Value="p" /> @p</label>。
- 在模型上使用数据注解定义校验规则(如 [Required, StringLength(100)]、[Required, EmailAddress]、[Range(18, 99)]),并在 EditForm 内添加 <DataAnnotationsValidator />,否则注解会被静默忽略。
- 用 <ValidationSummary /> 显示全部错误列表,用 <ValidationMessage For="() => Model!.FieldName" /> 显示单字段内联错误。
- 需要服务端往返校验(唯一性检查、业务规则)时,实现自定义校验器组件:继承 ComponentBase,通过 [CascadingParameter] 获取 EditContext,创建 ValidationMessageStore,在 OnInitialized 中订阅 EditContext.OnValidationRequested 清空消息、订阅 OnFieldChanged 清空对应字段消息,提供 DisplayErrors(Dictionary<string, List<string>>) 逐字段 Add 消息并调用 NotifyValidationStateChanged(),以及 ClearErrors() 清空并通知。
- 在表单中使用自定义校验器:<CustomValidator @ref="customValidator" />,提交时先 await RegistrationService.ValidateAsync(Model!),若有错误则 customValidator!.DisplayErrors(errors) 并 return,否则继续。
- 交互模式下用 @bind:after 在绑定值变化后执行逻辑,例如 <InputText @bind-Value="Model!.ZipCode" @bind:after="OnZipCodeChanged" />,在回调中根据新值调用服务并更新其他字段。
- 交互模式下用 @oninput 实现实时过滤,例如 <input type="text" @oninput="OnSearchInput" />,在处理器中读取 e.Value 并重新计算过滤列表。
- SSR 表单用 [SupplyParameterFromForm] 绑定 POST 数据,并在 OnInitialized 中用 ??= 初始化:GET 时为 null 会创建模型,POST 时框架已填充会保留提交值。
- 同一页面有多个表单时,每个 EditForm 设置唯一的 FormName,并让 [SupplyParameterFromForm(FormName = "search")] 与对应表单名匹配。
- 为获得类 SPA 的提交体验,在 EditForm 上添加 Enhance 属性,使表单通过 fetch 提交、修补 DOM 并保留滚动位置。
- 使用原生 <form> 而非 EditForm 时,必须手动添加 <AntiforgeryToken />,并设置 method="post"、@onsubmit 与 @formname;EditForm 会自动包含防伪令牌。
- 文件上传使用 InputFile(仅交互模式):<InputFile OnChange="OnFileSelected" accept=".pdf,.jpg,.png" />,在处理器中通过 e.File 获取文件并用 OpenReadStream(maxAllowedSize: 10 * 1024 * 1024) 读取流。注意 Server 默认约 30 KB SignalR 消息限制,需通过 maxAllowedSize 提高;WebAssembly 在浏览器读取,无 SignalR 限制但受内存约束。
- 多文件上传使用 <InputFile OnChange="OnFilesSelected" multiple />,在处理器中用 e.GetMultipleFiles(maxAllowedFiles: 10) 遍历,并对每个文件调用 OpenReadStream(maxAllowedSize: ...) 处理。
- 防止重复提交:用 disabled="@isSubmitting" 禁用提交按钮,并在处理器中先置 isSubmitting = true,在 try/finally 中执行保存并最终置回 false。
- 自定义校验 CSS 类:继承 FieldCssClassProvider 并重写 GetFieldCssClass,根据 editContext.GetValidationMessages(fieldIdentifier).Any() 与 editContext.IsModified(fieldIdentifier) 返回如 "is-valid"/"is-invalid",然后在 OnInitialized 中通过 editContext.SetFieldCssClassProvider(new BootstrapFieldCssClassProvider()) 应用。
- 避免在 Static SSR 表单中使用 @bind 或 @oninput,改用 [SupplyParameterFromForm] 与 FormName。
- 避免忘记在 OnInitialized 中写 Model ??= new()。
- 避免将 OnSubmit 与 OnValidSubmit/OnInvalidSubmit 混用。
- 避免省略 <DataAnnotationsValidator />。
- 避免在 SSR 多表单页面省略 FormName。
- 避免在 Static SSR 中使用 InputFile。
- 避免在 EditForm 上同时设置 Model 与 EditContext。
- 避免在原生 <form> 中省略 <AntiforgeryToken />。
适用边界 · 注意事项
- 项目脚手架搭建(应使用 create-blazor-project 技能)。
- 预渲染相关问题(应使用 support-prerendering 技能)。