ASP.NET MVC – Model Binding

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:

[csharp][/csharp] view plaincopy

  1. public class BindingController : Controller
  2. {
  3. public ActionResult Repeat(String text, Int32 number)
  4. {
  5. var model = new RepeatViewModel {Number = number, Text = text};
  6. return View(model);
  7. }
  8. }

Http Request : 采用Query String 方式

http://server/binding/repeat?text=Dino&number=2

2.  Complex type

Complex Type:

[csharp][/csharp] view plaincopy

  1. public class RepeatText
  2. {
  3. public String <strong>Text</strong> { get; set; }
  4. public Int32 <strong>Number</strong> { get; set; }
  5. }

Controller Method:

[csharp][/csharp] view plaincopy

  1. public class ComplexController : Controller
  2. {
  3. public ActionResult Repeat(RepeatText inputModel)
  4. {
  5. var model = new RepeatViewModel
  6. {
  7. Title = “Repeating text”,
  8. Text = inputModel.Text,
  9. Number = inputModel.Number
  10. };
  11. return View(model);
  12. }
  13. }

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 :

[html][/html] view plaincopy

  1. @using (Html.BeginForm())
  2. {
  3. <h2>List your email address(es)</h2>
  4. foreach(var email in Model.Emails)
  5. {
  6. <input type=”text” name=”emails” value=”@email” />
  7. <br />
  8. }
  9. <input type=”submit” value=”Send” />
  10. }

Controller Method:

 

[csharp][/csharp] view plaincopy

  1. public ActionResult Emails(IList<String> emails)
  2. {
  3. }

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:

[csharp][/csharp] view plaincopy

  1. public class Country
  2. {
  3. public Country()
  4. {
  5. Details = new CountryInfo();
  6. }
  7. public String Name { get; set; }
  8. public CountryInfo Details { get; set; }
  9. }
  10. public class CountryInfo
  11. {
  12. public String Capital { get; set; }
  13. public String Continent { get; set; }
  14. }

Controller Method:

[csharp][/csharp] view plaincopy

  1. [ActionName(“Countries”)]
  2. [HttpPost]
  3. public ActionResult ListCountriesForPost(IList<Country> countries)
  4. {
  5. }

Form:

[html][/html] view plaincopy

  1. @using (Html.BeginForm())
  2. {
  3. <h2>Select your favorite countries</h2>
  4. var index = 0;
  5. foreach (var country in Model.CountryList)
  6. {
  7. <fieldset>
  8. <div>
  9. <b>Name</b><br />
  10. <input type=”text”
  11.        name=”countries[@index].Name”
  12.        value=”@country.Name” /><br />
  13. <b>Capital</b><br />
  14. <input type=”text”
  15.        name=”countries[@index].Details.Capital”
  16.        value=”@country.Details.Capital” /><br />
  17. <b>Continent</b><br />
  18. @{
  19.     var id = String.Format(“countries[{0}].Details.Continent”, index++);
  20. }
  21. @Html.TextBox(id, country.Details.Continent)
  22. <br />
  23. </div>
  24. </fieldset>
  25. }
  26. <input type=”submit” value=”Send” />
  27. }

总结:

如果default model binder不能适应需求则需要开发custom model binder。例如用三个TextBox实现一个DateHelper。

标签