ASP.NET MVC Model Binding
2015-04-09 17:51
399 查看
本篇文章我们来谈论ASP.NET MVC框架中的Model Binding,即模型绑定。
MVC框架在处理HTTP请求时,将浏览器发过来的参数转变成.net对象,然后给Action方法的参数赋值,这个过程就会Model Binding。我们讨论以下几种情况:
1. 绑定简单类型
2. 绑定复杂类型
3. 绑定简单类型的数组或集合
4. 绑定复杂类型的数组或集合
MVC框架会从以下位置搜索参数:
1. Request.Form
2. RouteData.Values
3. RouteData.Values
4. Request.Files
首先,我们在项目中的Models文件夹下新建一个Person类,它的HomeAddress属性是Address类。
我们接下来的讨论都是围绕这两个类进行的。我们在一个View的表单中向服务器提交数据,MVC框架会将我们提交的数据作为参数传递给对应的Action方法。
下面是Action方法的代码
这时,当用户输入信息后提交表单时,name=”FirstName”的文本框中的值会被传递给Action方法的FirstName参数,name=”LastName”的文本框中的值会被传递给Action方法的LastName参数,name=”Age”的值会在强制类型转化后传递给int?类型的age参数。这个过程就是Model Binding。
修改成上面的代码后,MVC框架会从Form中提取出参数,然后自动创建person对象,然后给FirstName、LastName和Age这三个属性赋值。
如果在Form中包括上面的文本框,MVC框架在创建person对象后,会为person的HomeAddress属性new 一个Address对象,并把上面的三个值赋给对应的属性。
注意,name是HomeAddress.Country,而不是Address.Country。HomeAddress是属性名,Address是类型名
我们在Action方法的参数中可以通过一个同名的数组变量来接收
这时,我们通过下面的Action方法来接收复杂类型的集合
由于Form中的name是中括号开头的,中括号前面没有变量名,所以,我们的Action方法中的参数名无所谓,只要类型对上就可以了。这样就实现了向后台Post一个复杂类型的集合。
到了这里,可能会有个疑问,Form表单中以中括号开头,Action方法中的参数名可以随便起,如果我的Form中有两个类型的集合该如何处理?我做了个实例代码,我们一起来看一下。下面是表单
这个表单包含两个集合,input元素的name属性都是中括号开头的。下面是Action方法
你们猜能不能正常接收参数?答案是肯定的!
MVC框架在处理HTTP请求时,将浏览器发过来的参数转变成.net对象,然后给Action方法的参数赋值,这个过程就会Model Binding。我们讨论以下几种情况:
1. 绑定简单类型
2. 绑定复杂类型
3. 绑定简单类型的数组或集合
4. 绑定复杂类型的数组或集合
MVC框架会从以下位置搜索参数:
1. Request.Form
2. RouteData.Values
3. RouteData.Values
4. Request.Files
首先,我们在项目中的Models文件夹下新建一个Person类,它的HomeAddress属性是Address类。
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MvcModelBinding.Models { public class Person { public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } public Address HomeAddress { get; set; } } public class Address { public string Line1 { get; set; } public string Line2 { get; set; } public string City { get; set; } public string PostalCode { get; set; } public string Country { get; set; } } }
我们接下来的讨论都是围绕这两个类进行的。我们在一个View的表单中向服务器提交数据,MVC框架会将我们提交的数据作为参数传递给对应的Action方法。
绑定简单类型
View中的表单如下<form action="/Home/TestBinding" method="post"> <div> 姓 <input class="text-box single-line" id="FirstName" name="FirstName" type="text" value="" /> <br /> 名 <input class="text-box single-line" id="LastName" name="LastName" type="text" value="" /> <br /> 年龄 <input class="text-box single-line" id="Age" name="Age" type="number" value="" /> <br /> <input type="submit" value="提交" /> </div> </form>
下面是Action方法的代码
[HttpPost] public ActionResult TestBinding(string FirstName, string LastName,int? age) { return View(); }
这时,当用户输入信息后提交表单时,name=”FirstName”的文本框中的值会被传递给Action方法的FirstName参数,name=”LastName”的文本框中的值会被传递给Action方法的LastName参数,name=”Age”的值会在强制类型转化后传递给int?类型的age参数。这个过程就是Model Binding。
绑定复杂类型
如果Form中的值是一个对象的多个属性,我们可以简化一下Action方法的参数,接收一个对象就行了。[HttpPost] public ActionResult TestBinding(Person person) { return View(); }
修改成上面的代码后,MVC框架会从Form中提取出参数,然后自动创建person对象,然后给FirstName、LastName和Age这三个属性赋值。
复杂类型的某个属性还是复杂类型
在Person类中,HomeAddress属性是Address类型,如何为HomeAddress属性赋值呢?<input type="text" name="HomeAddress.Country" /> <input type="text" name="HomeAddress.City" /> <input type="text" name="HomeAddress.PostalCode" />
如果在Form中包括上面的文本框,MVC框架在创建person对象后,会为person的HomeAddress属性new 一个Address对象,并把上面的三个值赋给对应的属性。
注意,name是HomeAddress.Country,而不是Address.Country。HomeAddress是属性名,Address是类型名
绑定简单类型的数组或集合
我们有时候会遇到这种情况,Form中包含可变长度的数组,这就需要将这个数组传递到后台。我们以下面的表单来举例,数组元素的name属性具有相同的值<form action="/Home/Names" method="post"> <div> <label>1:</label> <input id="names" name="names" type="text" value="" /> </div> <div> <label>2:</label> <input id="names" name="names" type="text" value="" /> </div> <div> <label>3:</label> <input id="names" name="names" type="text" value="" /> </div> <button type="submit">Submit</button> </form>
我们在Action方法的参数中可以通过一个同名的数组变量来接收
[HttpPost] public ActionResult TestBinding(string[] names) { return View(); }
绑定复杂类型的数组或集合
我们假设这个问题更复杂,用户需要填写的这个不定长度的数组不仅只包含姓名,还需要包含其它信息。在绑定复杂类型时,我们一次提交了一个复杂对象,那么,我们可以一次提交多个复杂对象吗?看下面的表单<form action="/Home/AddressList" method="post"> <fieldset> <legend>Address 1</legend> <div> <label>City:</label> <input class="text-box single-line" name="[0].City" type="text" value="" /> </div> <div> <label>Country:</label> <input class="text-box single-line" name="[0].Country" type="text" value="" /> </div> </fieldset> <fieldset> <legend>Address 2</legend> <div> <label>City:</label> <input class="text-box single-line" name="[1].City" type="text" value="" /> </div> <div> <label>Country:</label> <input class="text-box single-line" name="[1].Country" type="text" value="" /> </div> </fieldset> </form>
这时,我们通过下面的Action方法来接收复杂类型的集合
[HttpPost] public ActionResult AddressList(IList<Address> addressList) { return View(); }
由于Form中的name是中括号开头的,中括号前面没有变量名,所以,我们的Action方法中的参数名无所谓,只要类型对上就可以了。这样就实现了向后台Post一个复杂类型的集合。
到了这里,可能会有个疑问,Form表单中以中括号开头,Action方法中的参数名可以随便起,如果我的Form中有两个类型的集合该如何处理?我做了个实例代码,我们一起来看一下。下面是表单
<form action="/Home/AddressList" method="post"> <fieldset> <legend>Address 1</legend> <div> <label>City:</label> <input class="text-box single-line" name="[0].City" type="text" value="" /> </div> <div> <label>Country:</label> <input class="text-box single-line" name="[0].Country" type="text" value="" /> </div> </fieldset> <fieldset> <legend>Address 2</legend> <div> <label>City:</label> <input class="text-box single-line" name="[1].City" type="text" value="" /> </div> <div> <label>Country:</label> <input class="text-box single-line" name="[1].Country" type="text" value="" /> </div> </fieldset> <p>下面是人员信息</p> <fieldset> <legend>Person 1</legend> <div> <label>FirstName:</label> <input class="text-box single-line" name="[0].FirstName" type="text" value="" /> </div> <div> <label>LastName:</label> <input class="text-box single-line" name="[0].LastName" type="text" value="" /> </div> </fieldset> <fieldset> <legend>Person 2</legend> <div> <label>FirstName:</label> <input class="text-box single-line" name="[1].FirstName" type="text" value="" /> </div> <div> <label>LastName:</label> <input class="text-box single-line" name="[1].LastName" type="text" value="" /> </div> </fieldset> <input type="submit" /> </form>
这个表单包含两个集合,input元素的name属性都是中括号开头的。下面是Action方法
[HttpPost] public ActionResult AddressList(IList<Address> addressList,IList<Person> personList) { return View(); }
你们猜能不能正常接收参数?答案是肯定的!
相关文章推荐
- ASP.NET MVC Model Binding(模型绑定)
- 深入ASP.NET MVC之六:Model Binding的实现
- Asp.net MVC Model Binding
- 有关ASP.NET MVC Model Binding知识的文章
- Model Binding in ASP.NET MVC
- Asp.net MVC ModelBinding 原理
- Asp.Net Mvc: Model Binding to Simple Types, Complex Types, Collections, Dictionaries, Etc
- Asp.Net Mvc: Model Binding to Simple Types, Co
- Asp.Net Mvc: Model Binding to Simple Types, Complex Types, Collections, Dictionaries, Etc
- [ASP.NET MVC] Model Binding With NameValueCollectionValueProvider
- 返璞归真 asp.net mvc (5) - Action Filter, UpdateModel, ModelBinder, Ajax, Unit Test
- 从零开始学习 ASP.NET MVC 1.0 (四) View/Model 全解 【转】
- Asp.Net Mvc: Implement your custom ModelBinder
- 合并model并且呈现(asp.net MVC)
- 返璞归真 asp.net mvc (5) - Action Filter, UpdateModel, ModelBinder, Ajax, Unit Test
- Asp.Net MVC之ViewData字典与ViewModel模式
- 从零开始学习 ASP.NET MVC 1.0 (四) View/Model 全解
- Asp.Net Mvc: Implement your custom ModelBinder
- Asp.net MVC 示例项目"Suteki.Shop"分析之---Model和Service
- Asp.net MVC 示例项目"Suteki.Shop"分析之---Model和Service