您的位置:首页 > 编程语言 > ASP

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类。

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();
}


你们猜能不能正常接收参数?答案是肯定的!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息