ASP.NET Core MVC 2.1 顶级参数验证
本文讨论ASP.NET Core 2.1中与ASP.NET Core MVC / Web API控制器中的模型绑定相关的功能。虽说这是一个功能,但从我的角度来看,它更像是一个错误修复!
请注意,我使用的是 NET Core 2.1 Preview 1,正式版发布后,功能可能存在变动。
ASP.NET Core 2.0 模型验证
模型验证是ASP.NET Core MVC 管线的重要组成部分。有很多方法可以注入到验证层(例如使用FluentValidation),最常见的方法可能是使用来自System.ComponentModel
的验证标记来修饰绑定模型。 例如:
public class UserModel
{
[Required, EmailAddress]
public string Email { get; set; }
[Required, StringLength(1000)]
public string Name { get; set; }
}
如果您在控制器的操作方法中使用UserModel
,MvcMiddleware
则会自动创建对象的新实例,绑定模型的属性并使用如下三个来源对其进行验证:
- 表单 - 当使用POST将表单发送到服务器时,发送到HTTP请求的主体中;
- 路由 - 在匹配路由后从URL段或默认值中获取;
- 查询字符串 - 在URL的末尾传递。
请注意,目前,作为JSON发送的数据默认情况下不会被绑定。如果您希望绑定请求体中的JSON数据,则需要使用此处所述的
[FromBody]
标记修饰模型。
在控制器Action方法中,可以简单地检查ModelState
属性,确定提供的数据是否有效:
public class CheckoutController : Controller
{
public IActionResult SaveUser(UserModel model)
{
if(!ModelState.IsValid)
{
// Something wasn't valid on the model
return View(model);
}
// The model passed validation, do something with it
}
}
这是非常标准的MVC内容,但是如果您不想创建整个绑定模型,但仍想验证传入数据,该怎么办?
ASP.NET Core 2.0 顶级参数
DataAnnotation
标记默认MVC验证系统使用的属性不必应用于类的属性,它们也可以应用于参数。这可能会导致您认为您可以完全替换UserModel
上面的示例中的以下内容:
MVC默认验证系统使用的DataAnnotation
标记不一定应用于类的属性,它们同样可以应用于参数。这可能会导致您认为可以完全替换上面示例中的UserModel
,如下所示:
public class CheckoutController : Controller
{
public IActionResult SaveUser(
[Required, EmailAddress] string Email
[Required, StringLength(1000)] string Name)
{
if(!ModelState.IsValid)
{
// Something wasn't valid on the model
return View(model);
}
// The model passed validation, do something with it
}
}
不幸的是,这是行不通的!在绑定属性时,验证属性将被忽略,并且ModelState.IsValid
始终是true
!
ASP.NET Core 2.1中的顶级参数
幸运的是,ASP.NET Core团队意识到了这个问题,并且已经将修补程序合并为ASP.NET Core 2.1的一部分。因此,上一节中的代码的行为与您所期望的一样,参数经过验证,并相应地进行了ModelState.IsValid
更新。
作为这项工作的一部分,您现在还可以使用[BindRequired]
标记修饰参数。当绑定非空值类型时,此标记很重要,因为使用[Required]
标记对这些属性并不能提供预期的行为。
这意味着您现在可以执行以下操作,并确保testId
参数已从路由参数中正确绑定,并且qty
参数已从查询字符串中绑定。在ASP.NET Core 2.1之前,它甚至不能编译!
[HttpGet("test/{testId}")]
public IActionResult Get([BindRequired, FromRoute] Guid testId, [BindRequired, FromQuery] int qty)
{
if(!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// Valid and bound
}
对于这个问题可以查阅我之前的博客:《ASP.NET Core MVC中的 [Required]与[BindRequired]》。
总结
在ASP.NET Core 2.0及以下版本中,应用于顶级参数的验证标记将被忽略,并且ModelState
不会更新。只考虑复杂模型类型的验证参数。
在ASP.NET Core 2.1中,验证标记现在将在顶级参数上得到遵守。更重要的是,您可以将[BindReqired]
标记应用于参数。
ASP.NET Core 2.1 增加了很多新特性。这是一些不错的小改进之一,它使事情变得更容易,更一致 -- 我喜欢这种改变。
翻译自https://andrewlock.net/coming-in-asp-net-core-2-1-top-level-mvc-parameter-validation/。
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!
欢迎各位转载,转载文章之后必须在文章页面明显位置给出作者和原文连接。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?