ASP.NET Core如何验证请求体中的RegistrationInput参数?
解决ASP.NET Core最小API中RegistrationInput验证不生效的问题
1. 正确给RegistrationInput添加验证特性
你用的是位置参数形式的record,需要把验证特性直接应用到对应参数上;或者改成属性形式的record,更便于维护。以下是两种实现方式:
写法一:位置参数record加特性
using System.ComponentModel.DataAnnotations; public record RegistrationInput( [StringLength(20, MinimumLength = 5, ErrorMessage = "登录名长度必须在5-20字符之间")] string login, [StringLength(100, MinimumLength = 6, ErrorMessage = "密码长度不能少于6位")] string password, [RegularExpression(@"^[А-Яа-яЁё]+$", ErrorMessage = "姓名只能包含西里尔字母")] string name, [RegularExpression(@"^[А-Яа-яЁё]+$", ErrorMessage = "姓氏只能包含西里尔字母")] string surname, [RegularExpression(@"^[А-Яа-яЁё]*$", ErrorMessage = "父名只能包含西里尔字母(可留空)")] string patronymic, [Range(1, int.MaxValue, ErrorMessage = "用户班级ID必须是正整数")] int UserClassId );
写法二:属性形式的record(更直观)
using System.ComponentModel.DataAnnotations; public record RegistrationInput { [StringLength(20, MinimumLength = 5, ErrorMessage = "登录名长度必须在5-20字符之间")] public string Login { get; init; } [StringLength(100, MinimumLength = 6, ErrorMessage = "密码长度不能少于6位")] public string Password { get; init; } [RegularExpression(@"^[А-Яа-яЁё]+$", ErrorMessage = "姓名只能包含西里尔字母")] public string Name { get; init; } [RegularExpression(@"^[А-Яа-яЁё]+$", ErrorMessage = "姓氏只能包含西里尔字母")] public string Surname { get; init; } [RegularExpression(@"^[А-Яа-яЁё]*$", ErrorMessage = "父名只能包含西里尔字母(可留空)")] public string Patronymic { get; init; } [Range(1, int.MaxValue, ErrorMessage = "用户班级ID必须是正整数")] public int UserClassId { get; init; } }
2. 在端点中启用并检查模型验证
ASP.NET Core最小API不会自动触发模型验证,需要手动绑定请求体并检查验证状态。修改你的注册端点代码如下:
using Microsoft.AspNetCore.Mvc; app.MapPost("/register", async ([FromBody] RegistrationInput inp, ThreeMoronsContext db, ModelStateDictionary modelState) => { // 优先检查模型验证结果 if (!modelState.IsValid) { // 返回所有验证错误信息给客户端 return TypedResults.BadRequest(modelState); } var HashingResult = PasswordMegaHasher.HashPass(inp.Password); try { User UserToRegister = new() { Id = Guid.NewGuid(), Login = inp.Login, Password = HashingResult.hashpass, Salt = HashingResult.salt.ToString(), Name = inp.Name, Surname = inp.Surname, Patronymic = inp.Patronymic, UserClassId = inp.UserClassId }; await db.Users.AddAsync(UserToRegister); await db.SaveChangesAsync(); // 记得取消注释这行,完成数据库写入 return Results.Ok(UserToRegister); } catch (Exception exc) { return TypedResults.BadRequest(exc.Message); } });
关键注意点
- 必须用
[FromBody]标记输入参数:ASP.NET Core才会自动解析请求体并应用数据注解的验证规则。 - 注入
ModelStateDictionary:用于获取验证失败的具体信息,判断输入是否符合要求。 - 验证失败时返回
BadRequest(modelState):会自动把所有错误信息打包返回,方便前端处理。
另外,你原来的代码注释了await db.SaveChangesAsync();,正式测试或部署时记得取消注释,否则用户数据不会真正保存到数据库。
内容的提问来源于stack exchange,提问作者Лев Поваляев
相关产品推荐
相关产品推荐

