Model Binding
What's Model Binding? (strong type view)
Model bindingis the process of creating .NET objects using the data sent by the browser in an HTTP request. We have been relying on the model binding process each time we have defined an action method that takes a parameter—the parameter objects are created by model binding.
Notes:
1. about naming, the action method's parameter name(e.g. id) should be well-defined. because model binder will search to generate the parameter based on the parameter name and the pre-defined search list. otherwise, it may cause call fail, as binder could not find a proper name.
1. Request.Form["id"]
2. RouteData.Values["id"]
3. Request.QueryString["id"]
4. Request.Files["id"]
2. be careful about the culture's impact on some data type, like datatime.
Binding to Simple Types
be careful about the actionmethod's parameter and check
e.g.
method is action(int id)
1. if the URL is /Home/Controllor/Apple, then it could not convert to int type automatically, so it will return a failed page
2. if we change the method to action(int? id), but if in action method, we use id parameter, then it will return a failed page either.
3. if we give the parameter a default value, like action(int id=3), then it's ok.
4. if the URL is /Home/Controller/-1, it also pass the convertion, but it may not follow the business rules. so need to check in this case.
Binding to Complex Types (e.g. ActionResult ActionMethod(complex type parameter))
When the action method parameter is a complex type(i.e., any type which cannot be converted using the TypeConverterclass), then the DefaultModelBinderclass uses reflection to obtain the set of public properties and then binds to each of them in turn.
That is only property could be bound as property name is something like LastName, while varaiable name could not be like this.
in order for ModelBinder working, the property names have to be shown in the View file, while if there is nest complex type, e.g. one person class has another class object, Address, the address's properties also need to be shown. as the binder will search the property name from "FORM" to generate the proper complex object.
We have used the strongly-typed EditorForhelper method, and specified the properties we want to edit from the HomeAddress property. The helper
automatically sets the name attributes of the input elements to match the format that the default model binder uses, as follows:
@Html.EditorFor(m=> m.HomeAddress.City)
...
<input class="text-box single-line" id="HomeAddress_Country" name="HomeAddress.Country"
type="text" value="" />
...
Specifying Custom Prefixes
Notes:
1. BeginFormhelper method could make the form is submitted back to the new DisplaySummaryaction method
@using(Html.BeginForm("DisplaySummary", "Home"))
if in the view file, we have something like summary.lastname property, and if we specify postback to new action method whose parameter is summary type, then by default, it will not generate summary type data. Because model binder will search the lastname in the form("lastname"), while in the form data, we only have form("summary.lastname"), so we need to add prefix in the new atcion method. like
public ActionResult DisplaySummary([Bind(Prefix="HomeAddress")]AddressSummary summary) {
return View(summary);
}
Selectively Binding Properties
1.the country property value will not be generated, this is only applied for this action method.
public ActionResult DisplaySummary(
[Bind(Prefix="HomeAddress", Exclude="Country")]AddressSummary summary) {
return View(summary);
}
2. this indicates only city property will be generated, this is applied for anything using this class.
namespace MvcModels.Models {
[Bind(Include="City")]
public class AddressSummary {
public string City { get; set; }
public string Country { get; set; }
}
}
Manually Invoking Model Binding
The model binding process is performed automatically when an action method defines parameters, but we can take direct control of the process if we want to. This gives us more explicit control over how model objects are instantiated, where data values are obtained from, and how data parsing errors are handled(when disable client side validation, it may cause bind error).
public ActionResult Address(FormCollection formData//where data from, in this case, it is form) {
IList<AddressSummary> addresses = new List<AddressSummary>();
try { //Handle error
UpdateModel(addresses, formData);
} catch (InvalidOperationException ex) {
// provide feedback to user
}
return View(addresses);
}
When model binding is invoked automatically, binding errors are not signaled with exceptions. Instead, we must check the result through the ModelState.IsValidproperty.
Customizing the Model Binding System
----
public class User
{
public string FirstName { get; set; }
public bool IsAdmin { get; set; }
}
@using (Html.BeginForm()) {
@Html.EditorFor(model => model.FirstName)
}

Weakly Typed Approaches
[HttpPost]
public ViewResult Edit([Bind(Include = "FirstName")] User user)
{
// ...
}
[HttpPost]
public ViewResult Edit([Bind(Exclude = "IsAdmin")] User user)
{
// ...
}
[HttpPost]
public ViewResult Edit()
{
var user = new User();
TryUpdateModel(user, includeProperties: new[] { "FirstName" });
// ...
}
Strongly Typed Approaches
[HttpPost]
public ViewResult Edit()
{
var user = new User();
TryUpdateModel<IUserInputModel>(user);
return View("detail", user);
}
public interface IUserInputModel
{
string FirstName { get; set; }
}
public class User : IUserInputModel
{
public string FirstName { get; set; }
public bool IsAdmin { get; set; }
}
public class User
{
public string FirstName { get; set; }
[ReadOnly(true)]
public bool IsAdmin { get; set; }
}
An Architectural Approach
public class UserInputViewModel
{
public string FirstName { get; set; }
}

浙公网安备 33010602011771号