ASP.NET Core MVC 2.1 顶级参数验证

2018 年 4 月 1 日 DotNet

(点击上方蓝字,可快速关注我们)


英文:andrewlock.net

来源:Sweet-Tang

译文:cnblogs.com/tdfblog/p/asp-net-core-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则会自动创建对象的新实例,绑定模型的属性并使用如下三个来源对其进行验证:


  1. 表单 - 当使用POST将表单发送到服务器时,发送到HTTP请求的主体中;


  2. 路由 - 在匹配路由后从URL段或默认值中获取;


  3. 查询字符串 - 在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]》(http://www.cnblogs.com/tdfblog/p/required-and-bindrequired-in-asp-net-core-mvc.html)。


总结


在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/。


看完本文有收获?请转发分享给更多人

关注「DotNet」,提升.Net技能 

淘口令复制以下红色内容,再打开手淘即可购买

范品社,使用¥极客T恤¥抢先预览(长按复制整段文案,打开手机淘宝即可进入活动内容)

登录查看更多
0

相关内容

ASP.NET 是一项微软的技术,是一种使嵌入网页中的脚本可由因特网服务器执行的服务器端脚本技术。 指 Active Server Pages(动态服务器页面),运行于 IIS 之中的程序 。
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
120+阅读 · 2020年5月10日
【资源】100+本免费数据科学书
专知会员服务
108+阅读 · 2020年3月17日
深度强化学习策略梯度教程,53页ppt
专知会员服务
183+阅读 · 2020年2月1日
TensorFlow Lite指南实战《TensorFlow Lite A primer》,附48页PPT
专知会员服务
70+阅读 · 2020年1月17日
Keras作者François Chollet推荐的开源图像搜索引擎项目Sis
专知会员服务
30+阅读 · 2019年10月17日
用Now轻松部署无服务器Node应用程序
前端之巅
16+阅读 · 2019年6月19日
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
使用 C# 和 Blazor 进行全栈开发
DotNet
6+阅读 · 2019年4月15日
去哪儿网开源DNS管理系统OpenDnsdb
运维帮
21+阅读 · 2019年1月22日
.NET Core 环境下构建强大且易用的规则引擎
Arxiv
5+阅读 · 2018年5月1日
Arxiv
7+阅读 · 2018年4月11日
Arxiv
3+阅读 · 2018年4月5日
Arxiv
5+阅读 · 2015年9月14日
VIP会员
相关资讯
用Now轻松部署无服务器Node应用程序
前端之巅
16+阅读 · 2019年6月19日
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
使用 C# 和 Blazor 进行全栈开发
DotNet
6+阅读 · 2019年4月15日
去哪儿网开源DNS管理系统OpenDnsdb
运维帮
21+阅读 · 2019年1月22日
.NET Core 环境下构建强大且易用的规则引擎
Top
微信扫码咨询专知VIP会员