ASP.NET Core Blazor 核心功能二:Blazor表单和验证
大家好,我是码农刚子。本文介绍了Blazor中EditForm组件的使用及表单验证方案。主要内容包括:
1)EditForm基础用法,通过Model参数绑定模型,使用DataAnnotationsValidator实现数据注解验证;
2)自定义验证规则实现,通过继承ComponentBase创建CustomValidator组件,结合ValidationMessageStore管理验证消息;
3)集成第三方验证库FluentValidation,展示如何定义复杂业务规则验证。文章提供了完整代码示例,涵盖内置验证、自定义验证和第三方验证三种方案,帮助开发者灵活处理Blazor表单验证需求。
一、EditForm 组件使用
Blazor 的 EditForm 是一个强大的组件,用于处理表单输入和验证。它通过绑定模型和验证逻辑,简化了表单的开发过程。以下是 EditForm 的核心功能和使用示例。
Blazor 表单内置组件

基本功能
EditForm 组件通过 Model 参数绑定到一个模型实例,并使用 DataAnnotationsValidator 组件支持基于数据注释的验证。它提供了以下事件回调:
- OnValidSubmit:当表单验证通过时触发。
- OnInvalidSubmit:当表单验证失败时触发。
- OnSubmit:无论验证状态如何,都会触发。
以下是一个简单的表单示例:
@page "/formsample" @using System.ComponentModel.DataAnnotations; <h3>表单</h3> <p>@stu.ToString()</p> <EditForm Model="@stu" OnValidSubmit="onValidSubmit" OnInvalidSubmit="onInvalidSubmit"> <DataAnnotationsValidator></DataAnnotationsValidator> <ValidationSummary></ValidationSummary> <div class="form-inline"> 姓名:<InputText @bind-Value="stu.name"></InputText> <ValidationMessage For="() => stu.name" /> </div> <div class="form-inline"> 年龄:<InputNumber @bind-Value="stu.age"></InputNumber> </div> <div class="form-inline"> 生日:<InputDate @bind-Value="stu.birthday"></InputDate> </div> <div class="form-inline"> 是否婚配: <InputCheckbox @bind-Value="stu.ismarried"></InputCheckbox> </div> <div class="form-inline"> 现居城市: <InputSelect @bind-Value="stu.city"> <option value="北京">北京</option> <option value="上海">上海</option> <option value="广州">广州</option> <option value="深圳">深圳</option> </InputSelect> </div> <button type="submit">Submit</button> </EditForm> @code { public class student { [Required] [StringLength(10, ErrorMessage = "名字最大长度不能超过10位")] public string name { get; set; } = "码农刚子"; //姓名 [Range(18, 45, ErrorMessage = "年龄必须在18-45岁之间")] public int age { get; set; } = 26; //年龄 public DateTime birthday { get; set; } = System.DateTime.Now;//生日 public string city { get; set; } = "深圳"; //所在城市 public bool ismarried { get; set; } = false; //是否婚配 public override string ToString() { return $"姓名:{name},年龄:{age},生日:{birthday},城市:{city},是否婚配:{ismarried}"; } } public student stu = new student() { }; private EditContext editContext; protected override void OnInitialized() { editContext = new EditContext(stu); } public void onSubmit() { Console.WriteLine("on onSubmit"); } public void onValidSubmit() { Console.WriteLine("on onValidSubmit"); } public void onInvalidSubmit() { Console.WriteLine(" onInvalidSubmit"); } }
验证与错误处理
通过 ValidationSummary 组件可以显示所有验证错误,而 ValidationMessage 组件可以针对特定字段显示错误信息。数据注释如 [Required] 和 [StringLength] 用于定义验证规则。
EditForm 提供了一系列数据验证的属性/方法,这样我们不用自己再去实现了。
|
属性/方法名 |
说明 |
|
Modal |
表单实体模型,必填 |
|
OnValidSubmit/OnInvalidSubmit |
提交表单时,验证通过/未通过 的回调函数 |
|
OnSubmit |
提交表单时的回调函数,和上面的两个属于“或”的关系, 使用了OnValidSubmit/OnInvalidSubmit就不能再使用OnSubmit。同理,使用了OnSubmit就不能使用OnValidSubmit/OnInvalidSubmit。 OnSubmit可以用来做一些自定义的验证 |
|
DataAnnotationsValidator
|
启用数据注解验证,就是特性验证。 |
|
ValidationSummary |
验证结果摘要。验证不合法时,会在表单的顶部用html标签显示具体错误。也是继承自ComponentBase的一种组件 |
二、自定义验证规则
自定义 ValidationMessageStore
如果需要更复杂的校验逻辑,可以使用 ValidationMessageStore 手动管理验证消息。
我们来自定义一个验证组件:
关于验证的组件思路,我们首先肯定是要从ComponentBase组件来集成,然后我们上面有学习到<EditForm>会定义一个级联值,我们自定义的组件也是嵌入到EditForm中,因此我们需要定义级联参数从而引用该值,我们先放代码:
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; namespace BlazorApp { public class CustomValidator:ComponentBase { private ValidationMessageStore messageStore; [CascadingParameter] private EditContext currentEditContext { get; set; } protected override void OnInitialized() { if (currentEditContext == null) { throw new InvalidOperationException($"{nameof(CustomValidator)} requires a cascading " + $"parameter of type {nameof(EditContext)}. For example, you can use {nameof(CustomValidator)} " + $"inside an EditForm."); } messageStore = new ValidationMessageStore(currentEditContext); currentEditContext.OnValidationRequested += (s, e) => messageStore.Clear(); currentEditContext.OnFieldChanged += (s, e) => messageStore.Clear(e.FieldIdentifier); } public void DisplayErrors(Dictionary<string, List<string>> errors) { foreach (var error in errors) { var fieldIdentifier = new FieldIdentifier(currentEditContext.Model, error.Key); messageStore.Add(fieldIdentifier, error.Value); } currentEditContext.NotifyValidationStateChanged(); } public void ClearErrors() { messageStore.Clear(); currentEditContext.NotifyValidationStateChanged(); } } }
我们需要注意到,在这个组件里我们同时监听了EditContext的onValidationRequest事件,以及OnFieldChange事件,同时我们使用了一个字段ValidationMessageStore, 主要是用于验证的消息保存,另外我们使用DisplayErrors 收集来自组件的错误信息,同时使用EditContext通知订阅了事件ValidationStateChanged的接收者。
然后我们在EditForm里应用该组件,代码如下:
@page "/formsample1" @using System.ComponentModel.DataAnnotations; <h3>表单</h3> <p>@stu.ToString()</p> <EditForm Model="@stu" OnValidSubmit="@HandleValidSubmit"> <DataAnnotationsValidator></DataAnnotationsValidator> <CustomValidator @ref="customValidator" /> <div class="form-inline"> 姓名:<InputText @bind-Value="stu.name"></InputText> <ValidationMessage For="() => stu.name" /> </div> <div class="form-inline"> 年龄:<InputNumber @bind-Value="stu.age"></InputNumber> <ValidationMessage For="() => stu.age" /> </div> <div class="form-inline"> 生日:<InputDate @bind-Value="stu.birthday"></InputDate> </div> <div class="form-inline"> 是否婚配: <InputCheckbox @bind-Value="stu.ismarried"></InputCheckbox> </div> <div class="form-inline"> 现居城市: <InputSelect @bind-Value="stu.city"> <option value="北京">北京</option> <option value="上海">上海</option> <option value="广州">广州</option> <option value="深圳">深圳</option> </InputSelect> </div> <button type="submit">Submit</button> </EditForm> @code { public class student { [Required] [StringLength(10, ErrorMessage = "名字最大长度不能超过10位")] public string name { get; set; } = "码农刚子"; //姓名 public int age { get; set; } = 26; //年龄 public DateTime birthday { get; set; } = System.DateTime.Now;//生日 public string city { get; set; } = "深圳"; //所在城市 public bool ismarried { get; set; } = false; //是否婚配 public override string ToString() { return $"姓名:{name},年龄:{age},生日:{birthday},城市:{city},是否婚配:{ismarried}"; } } public student stu = new student() { }; private CustomValidator customValidator; private ValidationMessageStore messageStore; private void HandleValidSubmit() { customValidator.ClearErrors(); var errors = new Dictionary<string, List<string>>(); if (stu.name == "admin") { errors.Add(nameof(stu.name), new List<string> { "姓名不能为 admin" }); } if (stu.age < 18 || stu.age > 60) { errors.Add(nameof(stu.age), new List<string> { "年龄必须在 18 到 60 岁之间" }); } if (errors.Count > 0) { customValidator.DisplayErrors(errors); } else { Console.WriteLine($"表单提交成功:{stu.ToString()}!"); } } }
三、第三方验证库(如 FluentValidation)
在 Blazor 应用中,使用像 FluentValidation 这样的第三方库来处理表单验证,可以让你摆脱内置数据注解的限制,更灵活地定义复杂的业务验证规则。社区提供了诸如 Blazored.FluentValidation 这样的库来简化集成工作。
1. 安装 NuGet 包
根据你选择的 FluentValidation Blazor 集成库,在项目目录下执行安装命令,或者手动打开管理NuGet程序包,搜索安装。例如,使用 Blazored.FluentValidation包:
dotnet add package FluentValidation
dotnet add package Blazored.FluentValidation
2. 创建模型与验证器
创建一个数据模型(例如 User 类)和对应的验证器类。
// 模型类 public class User { public string Name { get; set; } public string Email { get; set; } } // 验证器类 using FluentValidation; public class UserValidator : AbstractValidator<User> { public UserValidator() { // 定义验证规则 RuleFor(user => user.Name) .NotEmpty().WithMessage("姓名不能为空。") // 非空验证 .MaximumLength(10).WithMessage("姓名长度不能超过10个字符。"); // 最大长度验证 RuleFor(user => user.Email) .NotEmpty().WithMessage("邮箱地址不能为空。") .EmailAddress().WithMessage("请输入有效的邮箱地址。"); // 邮箱格式验证 } }
3. 注册验证器服务
在 Program.cs 文件中,将你的自定义验证器注册到依赖注入容器中。
using FluentValidation; // ... 其他服务配置 builder.Services.AddTransient<IValidator<User>, UserValidator>();
4. 在 Blazor 组件中使用
在你的 Razor 组件(.razor 文件)中,使用 <FluentValidationValidator> 组件来启用 FluentValidation。
@page "/user-form" @using BlazorApp.Data <!-- 根据实际使用的库引入命名空间 --> @using Blazored.FluentValidation @using FluentValidation <EditForm Model="@user" OnValidSubmit="HandleValidSubmit"> <!-- 使用 FluentValidation 验证器 --> <FluentValidationValidator /> <div class="form-group"> <label for="name">姓名:</label> <InputText id="name" @bind-Value="user.Name" class="form-control" /> <!-- 显示该字段的验证消息 --> <ValidationMessage For="@(() => user.Name)" /> </div> <div class="form-group"> <label for="email">邮箱:</label> <InputText id="email" @bind-Value="user.Email" class="form-control" /> <ValidationMessage For="@(() => user.Email)" /> </div> <button type="submit" class="btn btn-primary">提交</button> <!-- 显示验证摘要 --> <ValidationSummary /> </EditForm> @code { private User user = new User(); private void HandleValidSubmit() { // 当表单通过所有验证时,会执行此方法 Console.WriteLine($"提交用户:{user.Name}, {user.Email}"); // 这里可以添加提交数据到服务器的逻辑 } }
以上就是《ASP.NET Core Blazor 核心功能二:Blazor表单和验证》的全部内容,希望你有所收获。关注、点赞,持续分享。

浙公网安备 33010602011771号