Dot Net Stuff

Understanding Model Binding in ASP.NET MVC with Example


A view can display a form that has fields such as text boxes, check boxes, radio buttons, and so forth, and a submit button. When the user submits the form, the information in the fields is sent to the controller.ASP.NET uses an HttpRequest object to handle requests. Information coming in the request is stored in different collection objects depending on how the request was sent and the type of information. For example, if the request was sent via HTTP GET, such as http://www.DotNet-Tutorial.com/page?id=1&v=true, then the values for the parameters id and v are stored in the HttpRequest.QueryString collection. If the request is sent using HTTP POST, then the values are stored in the HttpRequest.Form collection. Uploaded files are stored in the HttpRequest.Files collection. If the request is based on a route, then the values are stored in the RouteData.Values dictionary.

When a user submits a form in a strongly typed view, ASP.NET MVC automatically examines the HttpRequest object and maps the information sent to fields in the model object. That way you only have to examine the model object for the information being sent. This process of mapping the information in the HttpRequest object to the model object is called "Model Binding".

Benefits of model binding in ASP.NET MVC

  1. No manual code is needed to extract the data from the HttpRequest object, which avoids coding errors.
  2. Data type conversions happen automatically.
  3. Data can be easily validated

Model binding is possible thanks to the built-in binder class DefaultModelBinder. This class is used by ASP.NET MVC when no custom binder classes are defined.

Let’s take an example of using a view model. The ASP.NET MVC 4 Internet project template used for our sample application created an AccountController class, an AccountModel.cs file with several models for handling user accounts, and some views in the Views/Account directory. If you open the Login.cshtml file in the Views/Account folder you will see the code shown below.

 
@model HaveYouSeenMe.Models.LoginModel
@{
ViewBag.Title = "Log in";
}
<hgroup class="title">
<h1>@ViewBag.Title.</h1>
</hgroup>
<section id="loginForm">
<h2>Use a local account to log in.</h2>
@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>Log in Form</legend>
<ol>
<li>
@Html.LabelFor(m => m.UserName)
@Html.TextBoxFor(m => m.UserName)
@Html.ValidationMessageFor(m => m.UserName)
</li>
<li>
@Html.LabelFor(m => m.Password)
@Html.PasswordFor(m => m.Password)
@Html.ValidationMessageFor(m => m.Password)
</li>
<li>
@Html.CheckBoxFor(m => m.RememberMe)
@Html.LabelFor(m => m.RememberMe, new { @class = "checkbox" })
</li>
</ol>
<input type="submit" value="Log in">
</fieldset>
<p>
@Html.ActionLink("Register", "Register") if you don't have an account.

} </section> <section class="social" id="socialLoginForm"> <h2>Use another service to log in.</h2> @Html.Action("ExternalLoginsList", new { ReturnUrl = ViewBag.ReturnUrl }) </section> @section Scripts { @Scripts.Render("~/bundles/jqueryval") }

This view is a strongly typed view based on the LoginModel class, which is located in Models/AccountModels.cs, This class contains the properties UserName, Password, and RememberMe. following code shows that-

 
public class LoginModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}

To understand how the view works, run the application from Visual Studio either by pressing the F5 key or choosing Debug -> Start Debugging. On the application home page, click the login link in the top-right corner of the page. On the web page that opens, right-click and select “Source” or “View Page Source,” depending on which browser you’re using, and you will see the HTML produced by the view. A part of the HTML is shown below.

<input name="__RequestVerificationToken" type="hidden" value="d57MEurvCdfdfdfdghtytwmA_66Cb1MeRfL_
zvYAqyKreGuOra7Il3BQETad6Bnfdhjferkuerie345454jfdfgFx22fMeZVy9FmtrkQ01">
<fieldset>
<legend>Log in Form</legend>
<ol>
<li>
<label for="UserName">User name</label>
<input data-val="true" data-val-required="The User name field is required." id="UserName" name="UserName" type="text" value="">
<span class="field-validation-valid" data-valmsg-for="UserName" data-valmsg-replace="true">
</span>
</li>
<li>
<label for="Password">Password</label>
<input data-val="true" data-val-required="The Password field is required." id="Password" name="Password" type="password">
<span class="field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"> </span>
</li>
<li>
<input data-val="true" data-val-required="The Remember me? field is required." id="RememberMe" name="RememberMe" type="checkbox" value="true"> <input name="RememberMe" type="hidden" value="false">
<label class="checkbox" for="RememberMe">Remember me?</label>
</li>
</ol>
<input type="submit" value="Log in">
</fieldset>
<p>
<a href="/Account/Register">Register</a> if you don't have an account.
</p>

When the user submits the form, the information is sent to the server using HTTP. At the server, the MVC routing mechanism deduces that it needs to invoke the Login() action method in the AccountController class. This action method expects a LoginModel object, so the MVC model binder creates a LoginModel object automaticall and it initializes the LoginModel object’s properties from the correspondingly named fields in the HTTP form. The LoginModel object is then passed into the Login() action method. Consider Following code, which shows the action method is actually expecting a LoginModel object as a parameter, instead of a low-level HttpRequest object.

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie:
model.RememberMe))
{
return RedirectToLocal(returnUrl);
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}

The WebSecurity.Login() method is then used to validate the username and password passed in the LoginModel object. If the validation is successful, the user is taken to the destination URL; otherwise, an error is generated and returned to the view to inform the user about it.

Summary: Now you can understand, how important the domain model is. It is formed by the data and business models. The data model is composed of the classes that interact with the database. The business model is in charge of all the server-related processing, including data processing, application-specific functionality, business rules, and more. The view models are in charge of sending information from controllers to views so that the views can properly render HTML to the client browser.


Keen to hear from you...!

If you have any questions related to what's mentioned in the article or need help with any issue, ask it, I would love to here from you. Please MakeUseOf Contact and i will be more than happy to help.

About the author

Anil Sharma is Chief Editor of dotnet-stuff.com. He's a software professional and loves to work with Microsoft .Net. He's usually writes articles about .Net related technologies and here to shares his experiences, personal notes, Tutorials, Examples, Problems & Solutions, Code Snippets, Reference Manual and Resources with C#, Asp.Net, Linq , Ajax, MVC, Entity Framework, WCF, SQL Server, jQuery, Visual Studio and much more...!!!

Loading