当MVC通过路由将请求映射到Action时,为了执行Action,首先需要进行模型绑定。那么,什么是模型绑定?
1. 理解模型绑定
模型绑定是将HTTP请求中的数据映射到MVC中Action方法的参数的过程。它发生在MVC 将请求路由到目标Controller 和目标Action 之后、Action 执行之前。
当找到目标Action方法时,为了执行它,首先需要检查其参数并为其赋值。这些参数的值通常是从当前请求中获取的。
//URL: /search?type=nameorder=descpublic IActionResult Search(string type, string order){ //.}Action方法的参数类型可以是简单的数据类型,如int、string等,也可以是复杂的数据类型,比如自定义类等。在进行模型绑定时,MVC会根据方法中的参数名称从HTTP请求中获取对应的数据。
默认情况下,MVC 认为HTTP 请求通过以下三种方式提供数据:
1、表单值:通过HTTP POST请求提交的一组表单数据;
2、路由值:通过路由中间件处理,给路由参数赋值;
3. 查询字符串:通过URL中的查询字符串提供;
以上数据源均以key-value的形式提供数据。模型绑定会根据指定的key(即Action方法的参数名)依次从上述三个位置查找参数值。上述三种情况如下图所示:
1. 从表格中获取
//获取@using(var form=Html.BeginForm()){ div @Html.LabelFor(m=m.FirstName) @Html.TextBoxFor(m=m.FirstName) /div div @Html.LabelFor(m=m .LastName) @Html.TextBoxFor(m=m.LastName) /div input type='submit' value='Submit' /}public IActionResult CreateUser(User user){ //.}2.从路线获取
请求URL:/home/index/3,约定路由模板:'{contoller}/{action}/{id?}'
public IActionResult(int id){ //.} 3. 从查询字符串中获取:
请求URL:/search?type=infoorder=desc
publicIActionResultSearch(stringtype,stringorder){//…} 可见模型绑定功能非常强大。它不仅可以为简单参数类型绑定值,还可以为自定义类提供绑定值。上例中的绑定表单值是将多种简单数据类型的值映射到自定义类中。做这个绑定的时候,模型绑定会根据自定义类的属性名进行绑定,将数据进行绑定。源中的相应参数被分配给自定义类中的同名属性。
因此,当自定义类作为Action方法的参数时,它必须有一个默认的构造函数(即无参数的公共类型),并且需要模型绑定赋值的属性也应该是带有get和set的公共类型段,支持属性值的读写。
公共类用户{公共字符串名字{获取;放; } 公共字符串姓氏{ 获取;放; }}当绑定失败时,例如在所有数据源中都没有找到期望的值,模型绑定不会抛出异常发生。反之,它会为Action参数提供对应参数类型的默认值。例如,字符串为null,int 为0,自定义类是一个属性包含默认值的实例。
提示:为了检查绑定是否成功,可以使用ControllerBase类提供的Model属性的IsValid属性来检查绑定是否有问题。 ModelState 属性表示包含ModelStateEntry 的集合,其中包含所有绑定错误的情况。
2. 定制绑定方式
我们刚刚讨论的绑定是模型绑定提供的默认方法。 MVC 提供了一些可用于更改参数获取值的方式的功能。它们包括:
1. [FromHeader]:从HTTP消息头中获取参数的值。 HTTP消息头还包含一组key-value形式的值;
2. [FromQuery]:从查询字符串中获取参数的值;
3. [FromRoute]:从路由中获取参数的值;
4.【FromFrom】:从表单数据中获取参数的值;
5、【FromBody】:从HTTP请求的body中获取参数的值(这种方式只能获取同一个Action中的一个参数);
6、【FromServices】:从依赖注入容器中获取参数的值(这种方式提供的数据不是从HTTP请求中获取的);
7.【ModelBinder】:使用自定义模型绑定为参数提供值。自定义模型绑定需要实现IModelBinder接口;
通过使用这些属性,您可以更改Action 方法参数获取其值的方式。此外,还有其他两个属性控制模型绑定的行为:
1. [BindRequired]:必须需要绑定。如果绑定失败,会在ModelState中添加错误信息;
2. [BindNever]:模型绑定不会处理该参数;
要使用上述功能,只需添加相应的参数即可:
public IActionResult([FromQuery] intparameter1, [FromHeader(Name='CustomHeader')] stringparameter2, [FromService] IDataServiceparameter3, [FromBody]Userparameter4){ //.} 最后需要注意的是,使用时在[FromBody]模式下,MVC将根据为其配置的Data Input Formatter来处理(即反序列化)数据。
默认情况下,ASP.NET Core 包含一个用于处理JSON 数据的JsonInputFormatter,用于将请求正文JSON 内容反序列化为.NET 对象。因此,默认情况下,提供的数据应为JSON 格式。而如果你想使用其他格式,比如XML,你应该向MVC添加对应格式的数据输入格式化程序。
用户评论
这篇文章真的让我对ASP.NET Core的模型绑定有了更深的理解,之前总是觉得这个功能很复杂,现在一看原来这么简单。
有12位网友表示赞同!
模型绑定这部分讲得还是挺详细的,不过能不能再深入讲讲它在不同场景下的应用呢?
有5位网友表示赞同!
刚刚看完,感觉模型绑定确实是个挺重要的功能,但是我有点看不懂,能有人帮忙解释一下吗?
有15位网友表示赞同!
模型绑定这部分,作者提到了很多高级用法,我之前根本不知道,学到了不少新知识。
有8位网友表示赞同!
看了这篇文章,感觉自己之前的代码写得太糙了,以后得好好利用模型绑定来优化一下。
有9位网友表示赞同!
对于初学者来说,这篇文章可能有点难度,如果能加上一些实例代码就更好了。
有20位网友表示赞同!
模型绑定这部分讲得不错,但是我觉得可以加入一些性能优化的建议。
有20位网友表示赞同!
这篇文章让我对ASP.NET Core的模型绑定有了全新的认识,感谢作者的分享。
有5位网友表示赞同!
之前对模型绑定一窍不通,现在看了这篇文章,感觉自己可以尝试自己写一个简单的应用了。
有10位网友表示赞同!
模型绑定这部分确实挺有意思的,不过我觉得可以增加一些实际案例来辅助理解。
有10位网友表示赞同!
看了这篇文章,我对ASP.NET Core的模型绑定有了更全面的了解,真的受益匪浅。
有15位网友表示赞同!
模型绑定这部分,作者提到了很多常见的坑,感觉以后开发的时候可以避免这些错误。
有15位网友表示赞同!
这篇文章让我对ASP.NET Core的模型绑定有了新的认识,特别是它如何提高开发效率的部分。
有18位网友表示赞同!
对于新手来说,这篇文章可能会有些难以理解,希望作者能考虑出一个更入门的版本。
有19位网友表示赞同!
模型绑定这部分,我之前一直觉得很难,现在感觉其实并不复杂,感谢作者的文章。
有14位网友表示赞同!
这篇文章让我对ASP.NET Core的模型绑定有了更深入的理解,感觉自己的技能又提升了。
有16位网友表示赞同!
模型绑定这部分,我觉得可以结合一些实际的项目案例来讲解,这样更直观。
有14位网友表示赞同!
看了这篇文章,我对ASP.NET Core的模型绑定有了全新的认识,感觉自己的编程水平又上升了一个台阶。
有5位网友表示赞同!
这篇文章讲得太好了,模型绑定这部分我之前一直不太懂,现在感觉清晰多了。
有20位网友表示赞同!