Http Request 到Input Model的绑定按照model的类型可分为四种情况。
- Primitive type
- Collection of primitive type
- Complex type
- Collection of complex type
首先理解Value Privider and Precedence
Model Binder是利用Value Provider来获取相关数据的。
1. Primitive type
Controller Method:
public class BindingController : Controller
{
public ActionResult Repeat(String text, Int32 number)
{
var model = new RepeatViewModel {Number = number, Text = text};
return View(model);
}
}
Http Request : 采用Query String 方式
http://server/binding/repeat?text=Dino&number=2
2. Complex type
Complex Type:
public class RepeatText
{
public String Text { get; set; }
public Int32 Number { get; set; }
}
Controller Method:
public class ComplexController : Controller
{
public ActionResult Repeat(RepeatText inputModel)
{
var model = new RepeatViewModel
{
Title = "Repeating text",
Text = inputModel.Text,
Number = inputModel.Number
};
return View(model);
}
}
Http Request : 采用Query String 方式
http://server/binding/repeat?text=Dino&number=2
Model Binder 将从posted data中寻找Key name与Property Name匹配的。从而可以实例化RepeatText对象。
3. Collection of primitive type
Form :
@using (Html.BeginForm())
{
<h2>List your email address(es)</h2>
foreach(var email in Model.Emails)
{
<input type="text" name="emails" value="@email" />
<br />
}
<input type="submit" value="Send" />
}
Controller Method:
public ActionResult Emails(IList<String> emails)
{
...
}
In the end, to ensure that a collection of values is passed to a controller method, you need to
ensure that elements with the same ID are emitted to the response stream.
4. Collection of complex type
Complex Type:
public class Country
{
public Country()
{
Details = new CountryInfo();
}
public String Name { get; set; }
public CountryInfo Details { get; set; }
}
public class CountryInfo
{
public String Capital { get; set; }
public String Continent { get; set; }
}
Controller Method:
[ActionName("Countries")]
[HttpPost]
public ActionResult ListCountriesForPost(IList<Country> countries)
{
...
}
Form:
@using (Html.BeginForm())
{
<h2>Select your favorite countries</h2>
var index = 0;
foreach (var country in Model.CountryList)
{
<fieldset>
<div>
<b>Name</b><br />
<input type="text"
name="countries[@index].Name"
value="@country.Name" /><br />
<b>Capital</b><br />
<input type="text"
name="countries[@index].Details.Capital"
value="@country.Details.Capital" /><br />
<b>Continent</b><br />
@{
var id = String.Format("countries[{0}].Details.Continent", index++);
}
@Html.TextBox(id, country.Details.Continent)
<br />
</div>
</fieldset>
}
<input type="submit" value="Send" />
}
总结:
如果default model binder不能适应需求则需要开发custom model binder。例如用三个TextBox实现一个DateHelper。