While ViewData and ViewBag (and TempData) are easy to use, they are not suitable for more complex scenarios that include any of the following:
• Master-detail data.
• Larger sets of data.
• Complex relational data.
• Reporting and aggregate data.
• Dashboards.
• Data from disparate sources.
• Data sent from the view to the controller.
For such scenarios, it is better to use a view model object. When you associate a view model to a view, the view become a strongly typed view. For now, simply understand that a view model is a class with properties that represent information that you want to pass from the controller action method to the view, so that the view can render it.
An example of a view model class is presented in Listing 1. Note that it is just a class with properties, and each property is decorated with some attributes.
Listing 1. A View Model Class
public class LoginModel
{
[Required(ErrorMessage = "The UserName is required")]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required(ErrorMessage = "The Password is required")]
[StringLength(20, MinimumLength = 6, ErrorMessage = "The Password is invalid")]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
In this case, we need to tell the view that it has an associated view model. We do so with the @model directive, as shown in Listing 2, which is generated automatically when you specify the model class in the Add View dialog.
Listing 2. Strongly Typed View Using the LoginModel View Model Class
@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)
</li>
<li>
@Html.LabelFor(m => m.Password)
@Html.PasswordFor(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.
</p>
}
</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")
}
What’s important about a strongly typed view is that it not only enables you to pass information back and forth to a controller but also enables you to use the view model properties simply by calling the implicit Model object. Note that the Model object is written with capital M as opposed to the model declaration with the @model statement. Visual Studio also makes the list of properties available in IntelliSense, as shown in Figure 1.

Figure 1. Properties of the view model object displayed in Visual Studio IntelliSense
Additionally, you can use the view model object’s properties in HTML helper methods, and you don’t even need to reference the Model object. For example:
@Html.LabelFor(m => m.UserName)
@Html.TextBoxFor(m => m.UserName)
These two helper methods will create a label and a text box, respectively, based on the attributes set for the property UserName in the view model class. The following is the rendered HTML for the two lines:
<label for="UserName">User name</label>
<input data-val="true" data-val-required="The UserName is required" id="UserName" name="UserName" type="text" value="" />
• Master-detail data.
• Larger sets of data.
• Complex relational data.
• Reporting and aggregate data.
• Dashboards.
• Data from disparate sources.
• Data sent from the view to the controller.
For such scenarios, it is better to use a view model object. When you associate a view model to a view, the view become a strongly typed view. For now, simply understand that a view model is a class with properties that represent information that you want to pass from the controller action method to the view, so that the view can render it.
An example of a view model class is presented in Listing 1. Note that it is just a class with properties, and each property is decorated with some attributes.
Listing 1. A View Model Class
public class LoginModel
{
[Required(ErrorMessage = "The UserName is required")]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required(ErrorMessage = "The Password is required")]
[StringLength(20, MinimumLength = 6, ErrorMessage = "The Password is invalid")]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
In this case, we need to tell the view that it has an associated view model. We do so with the @model directive, as shown in Listing 2, which is generated automatically when you specify the model class in the Add View dialog.
Listing 2. Strongly Typed View Using the LoginModel View Model Class
@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)
</li>
<li>
@Html.LabelFor(m => m.Password)
@Html.PasswordFor(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.
</p>
}
</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")
}
What’s important about a strongly typed view is that it not only enables you to pass information back and forth to a controller but also enables you to use the view model properties simply by calling the implicit Model object. Note that the Model object is written with capital M as opposed to the model declaration with the @model statement. Visual Studio also makes the list of properties available in IntelliSense, as shown in Figure 1.
Figure 1. Properties of the view model object displayed in Visual Studio IntelliSense
Additionally, you can use the view model object’s properties in HTML helper methods, and you don’t even need to reference the Model object. For example:
@Html.LabelFor(m => m.UserName)
@Html.TextBoxFor(m => m.UserName)
These two helper methods will create a label and a text box, respectively, based on the attributes set for the property UserName in the view model class. The following is the rendered HTML for the two lines:
<label for="UserName">User name</label>
<input data-val="true" data-val-required="The UserName is required" id="UserName" name="UserName" type="text" value="" />
No comments:
Post a Comment