原文:Model Binding
作者:Rachel Appel
翻译:娄宇(Lyrics)
校对:许登洋(Seay)、何镇汐
模型绑定介绍
ASP.NET Core MVC 中的模型绑定从 HTTP 请求参数中将数据映射到 Action 方法里。这些参数可以是 string、interger、float 这样的简单类型,也可以是复杂类型。这是 MVC 一个非常棒的功能,因为无论传入数据的大小或复杂性如何,映射传入数据到对应项是一个经常重复的情况。 MVC 通过抽象绑定解决了这个问题,所以开发者们不必继续在每一个应用中反复编写同样的代码。自己编写文本到类型转换的代码是冗长并且容易出错的。
模型绑定如何工作
当 MVC 收到一个 HTTP 请求,它将其路由到一个 Controller 特定的一个 Action 方法。它基于路由数据来决定运行哪个 Action 方法,然后将值从 HTTP 请求绑定到 Action 方法的参数中。例如,考虑下面的 URL:
http://contoso.com/movies/edit/2
因为路由模板看起来像这样,{controller=Home}/{action=Index}/{id?}
, movies/edit/2
路由到Movies
Controller ,和它的 Edit
Action 方法。同时接受到一个可选参数 id
。 Action 方法代码应该看起来像这样:
public IActionResult Edit(int? id)
提示
URL 中的字符串不区分大小写。
MVC 尝试通过参数名将请求数据绑定到 Action 的参数上。 MVC 将使用参数名以及它的公开可设置的属性名称查询所有的值。在上面的例子中,只有一个参数命名为 id
,MVC 将路由值中名称相同的值绑定过去。除了路由值之外, MVC 会以一种固定的顺序从 HTTP 请求中的其他部分绑定数据。下面是模型绑定的数据源列表的绑定顺序:
-
Form values
:这是通过 HTTP POST 请求发送的表单数据(包括 jQuery POST 请求)。 -
Route values
:由 routing 提供的路由数据集。 -
Query strings
:URI 的查询字符串的一部分。
提示
表单值,路由数据,以及查询字符串都以键值对的形式存储。
因为模型绑定要找一个命名为 id
的键,但是在表单值里没有命名为 id
的键,所以接下来将在路由数据中找寻这个键。在我们的例子中,它是匹配的。绑定发生时,该值转换为 integer 类型的 2。相同的请求使用 Edit(string id) 将转换成 string 类型的值 “2” 。
到目前为止的例子使用的都是简单类型。在 MVC 中简单类型是任何 .NET 原始类型或者带字符串的类型的转换器。如果 Action 方法的参数是一个类,比如说 Movie
类型,这个类包含简单类型和复杂类型的属性,MVC 的模型绑定仍然可以很好的处理它。它使用反射和递归遍历复杂类型寻找匹配的属性。模型绑定寻找 parameter_name.parameter_name 的模式去绑定值到属性上。如果没有从表单中找到匹配的值,将尝试只通过 property_name 进行绑定。对于那些 集合(Collection)
类型,模型绑定会去匹配 parameter_name[index] 或者只是 [index] 。模型绑定对待 字典(Dictionary)
类型也是一样,寻找 parameter_name[key] 或只是 [key] ,前提是 Key 是简单类型。 Key 支持匹配 HTML 和 Tag Helpers 为相同的模型类型生成的字段名。当创建或者编辑的绑定数据未通过验证的时候,回传值使得用户输入的表单字段仍然保留,方便了用户(不必重新输入全部数据)。
为了绑定发生,这个类必须有一个公开的默认构造函数,并且被绑定的成员必须是公开的,并且可写的属性。当模型绑定发生的时候只会通过默认的构造函数去实例化类型,然后设置属性的值。
当一个参数被绑定,模型绑定停止继续查找这个参数名并开始绑定下一个参数。如果绑定失败, MVC 不会抛出异常。你可以查询模型状态异常通过检查 ModelState.IsValid
属性。
提示
Controller 的ModelState
属性中的每个 Entry 都是一个包含了Errors 属性
的ModelStateEntry
。 你基本不需要去查询这个集合。使用ModelState.IsValid
来替代它。
此外,还有一些特殊的数据类型在 MVC 执行模型绑定的时候需要考虑:
-
IFormFile
,IEnumerable<IFormFile>
: 一个或多个通过 HTTP 请求上传的文件。 -
CancelationToken
:用于在异步 Controller 中取消活动。
这些类型可以被绑定到 Action 参数或者一个类的属性中。
一旦模型绑定完成,就会进行 验证 。默认的模型绑定适合绝大多数开发场景。它也是可扩展的,所以如果你有独特的需求,你可以自定义内置的行为。
通过 Attributes 自定义模型绑定行为
MVC 包含几种让你可以指定与默认绑定源不同行为的 Attribute 。比如,你可以通过使用 [BindRequired]
或者 [BindNever]
Attribute 指定一个属性是否需要绑定,或者它是否应该不发生。另外你可以替换默认的数据源,指定模型绑定器(Model Binder)的数据源。下面的是模型绑定 Attribute 的列表:
-
[BindRequired]
:这个 Attribute 表示如果这个绑定不能发生,将添加一个模型状态错误(Model State Error)。 -
[BindNever]
:告诉模型绑定器(Model Binder)这个参数不进行绑定。 -
[FromHeader]
,[FromQuery]
,[FromRoute]
,[FromForm]
:通过这些来指定期望的绑定源。 -
[FromServices]
:这个 Attribute 使用 dependency injection 通过服务来绑定参数。 -
[FromBody]
:使用配置好的格式化器来 从 HTTP 请求 Body 中绑定数据。格式化器的选择基于 HTTP 请求的 Content-Type[ModelBinder]
:用来替换默认的模型绑定器(Model Binder),绑定源和名字。
当你需要替换模型绑定的默认行为时,Attribute 是非常有用的工具。
从 Http Request 的 body 中绑定格式化数据
HTTP 请求数据能够支持各种各样的格式,包括 JSON 、XML 以及许多其它的格式。当你使用 [FromBody] 特性的时候表示你想要从 HTTP 请求的 Body 中绑定参数, MVC 使用一个格式化器的配置集来处理与 HTTP 请求的 Content-Type 对应的请求数据。默认情况下 MVC 包含一个 JsonInputFormatter
类用来处理 JSON 数据,但是你可以添加额外的格式化器来处理 XML 或者其它自定义格式。
提示
JsonInputFormatter
是默认的格式化器,它是基于 Json.NET。
ASP.NET 选择输入格式化器基于 Content-Type Header 以及参数的类型,除非这里有一个 Attribute 去指定其它的。如果你更喜欢使用 XML 或者其他格式,你必须在 Startup.cs 文件中进行配置,但是首先你必须使用 NuGet 引用 Microsoft.AspNetCore.Mvc.Formatters.Xml
。你的启动代码看起来应该像这样:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddXmlSerializerFormatters();
}
Startup.cs 文件中的代码包含了一个带有 services
参数的 ConfigureServices
方法,你可以使用它来为你的 ASP.NET 应用构建服务。在示例中,我们添加一个 XML 格式化器作为一个在此应用中 MVC 能够提供的的服务。 options
参数传入 AddMvc
方法允许你去添加和管理过滤器(Filter),格式化器(Formatter),以及其它 MVC 的系统选项从应用中启动。然后应用 各种各样的
Attribute 到 Controller 类或者 Action 方法上去实现你预期的效果。
ASP.NET Core 中文文档 第四章 MVC(2.1)模型绑定的更多相关文章
-
ASP.NET Core 中文文档 第四章 MVC(4.2)控制器操作的路由
原文:Routing to Controller Actions 作者:Ryan Nowak.Rick Anderson 翻译:娄宇(Lyrics) 校对:何镇汐.姚阿勇(Dr.Yao) ASP.NE ...
-
ASP.NET Core 中文文档 第四章 MVC(3.6.1 )Tag Helpers 介绍
原文:Introduction to Tag Helpers 作者:Rick Anderson 翻译:刘浩杨 校对:高嵩(Jack) 什么是 Tag Helpers? Tag Helpers 提供了什 ...
-
ASP.NET Core 中文文档 第四章 MVC(3.8)视图中的依赖注入
原文:Dependency injection into views 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:孟帅洋(书缘) ASP.NET Core 支持在视图中使用 依赖 ...
-
ASP.NET Core 中文文档 第四章 MVC(4.6)Areas(区域)
原文:Areas 作者:Dhananjay Kumar 和 Rick Anderson 翻译:耿晓亮(Blue) 校对:许登洋(Seay) Areas 是 ASP.NET MVC 用来将相关功能组织成 ...
-
ASP.NET Core 中文文档 第四章 MVC(4.5)测试控制器逻辑
原文: Testing Controller Logic 作者: Steve Smith 翻译: 姚阿勇(Dr.Yao) 校对: 高嵩(Jack) ASP.NET MVC 应用程序的控制器应当小巧并专 ...
-
ASP.NET Core 中文文档 第四章 MVC(4.4)依赖注入和控制器
原文: Dependency Injection and Controllers 作者: Steve Smith 翻译: 刘浩杨 校对: 孟帅洋(书缘) ASP.NET Core MVC 控制器应通过 ...
-
ASP.NET Core 中文文档 第四章 MVC(4.1)Controllers, Actions 和 Action Results
原文:Controllers, Actions, and Action Results 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:许登洋(Seay) Action 和 acti ...
-
ASP.NET Core 中文文档 第四章 MVC(3.9)视图组件
作者: Rick Anderson 翻译: 娄宇(Lyrics) 校对: 高嵩 章节: 介绍视图组件 创建视图组件 调用视图组件 演练:创建一个简单的视图组件 附加的资源 查看或下载示例代码 介绍视图 ...
-
ASP.NET Core 中文文档 第四章 MVC(3.7 )局部视图(partial)
原文:Partial Views 作者:Steve Smith 翻译:张海龙(jiechen).刘怡(AlexLEWIS) 校对:许登洋(Seay).何镇汐.魏美娟(初见) ASP.NET Core ...
-
ASP.NET Core 中文文档 第四章 MVC(01)ASP.NET Core MVC 概览
原文:Overview of ASP.NET Core MVC 作者:Steve Smith 翻译:张海龙(jiechen) 校对:高嵩 ASP.NET Core MVC 是使用模型-视图-控制器(M ...
随机推荐
-
Eclipse 调试 Java 程序的技巧
- 断点视图 : 条件断点 如果你只对应用中的某部分感兴趣的话,这个功能非常有用.例如,如果你要在第13次循环的时候检查程序,或者在一个抽象父类中调试某些功能,而你只关注其中一个具体的实现.你可以在断 ...
-
右键菜单添加程序,指定图标, Notepad2、Sublime Text 2
右键添加Sublime Text 打开方式 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\*\shell\Sublime Text] ...
-
linux源代码阅读笔记 linux文件系统(三)
当系统申请一个新的inode时.系统并不会对磁盘进行读写.它会在存储在内存的inode表(inode_table)中寻找一个空闲的位置. 如果找到了,直接返回该inode.否则要等待一个空闲的位置. ...
-
[模拟炉石](一)让游戏过程显示到cocos2d中
在上篇中,如果运行了fireplace的tests/full_game.py,这个程序将一个游戏过程在终端上运行完成,可以看到整个过程,那么第一步要做的就是将这个过程显示到cocos2d创建的场景中去 ...
-
C#访问C++动态分配的数组指针
项目中遇到C#调用C++算法库的情况,C++内部运算结果返回矩形坐标数组(事先长度未知且不可预计),下面方法适用于访问C++内部分配的任何结构体类型数组.当时想当然的用ref array[]传递参数, ...
-
Python 集体智慧编程PDF
集体智慧编程PDF 1.图书思维导图http://www.pythoner.com/183.html p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12. ...
-
linq分组求和_实体类和datatable
1.数据分组求合,分别用的实体类以及datatable来分组求合,还有分组求和之后的如何取值 //实体类版本 List<ProgramTimeModel> TotalAllList = G ...
-
SEO学习知识
监控流量的工具 百度统计 CNZZ 51LA 谷歌分析工具 如何从平台借流量? 竞价(付费).SEO 关键词定位: 定位人:负责人 将公司的业务全部列出来 选词: 根据定位的关键词选择出我们需要优化 ...
-
简易解说拉格朗日对偶(Lagrange duality)
引言:尝试用最简单易懂的描述解释清楚机器学习中会用到的拉格朗日对偶性知识,非科班出身,如有数学专业博友,望多提意见! 1.原始问题 假设是定义在上的连续可微函数(为什么要求连续可微呢,后面再说,这里不 ...
-
POJ 2112 Optimal Milking (Dinic + Floyd + 二分)
Optimal Milking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 19456 Accepted: 6947 ...