Knowledge Point 5-1: View Model

Source: Internet
Author: User

For an online store, the domain model may be composed of classes that represent products, orders, and customers. It closes the data and business rules defining these entities, this model serves as the basis for creating user interfaces and defining business rules. Although this approach may be suitable for some applications (usually small applications with simple domains), it is often troublesome, especially when the application grows, when the UI is required to deviate from the business logic requirements, a conflict of interests may lead to software that is too complex and cannot be maintained.

The solution to this problem is to introduce the view model to simplify the logic required for rendering the user interface. We will examine how to define the view model and send the user interface data back to the input model at the Controller layer.

I. What is a view model?

The purpose of the view model is very simple. It is a model specially designed for the view. It provides a simplified interface built on the domain model to minimize the view decision.

1. Add a view model in this example.

In this example, the guestbookentry class serves both as a domain model and a view model. It represents both the data stored in the database and the fields on the user interface.

This is sufficient for small applications such as message books. However, as the complexity of applications increases, when the complex user interface structure must not directly map the structure of the model, that is, the view data is different from the model structure, and the two must be separated. For example, let's add a new page to the guestbook application to show the summary of the comments that each user has submitted ,.

To create this screen, you must first create a view model. Each column contains an Attribute-User Name and number of submitted comments:

    public class CommentSummary    {        public string UserName { get; set; }        public string NumberOfComments { get; set; }    }

Now you need to create a controller action, query the database to obtain the required data for display, and then inject it into the commentsummary class instance.

      public ActionResult CommentSummary()        {            var entries = from entry in _db.Entries                          group entry by entry.Name into groupedByName                          orderby groupedByName.Count() descending                          select new CommentSummary                          {                              NumberOfComments = groupedByName.Count(),                              UserName = groupedByName.Key                          };            return View(entries.ToList());        }

Here, we use LINQ to query the message book data and group submitted comments by user name. The data is projected into a view model instance and then transmitted to the view.

@model IEnumerable<Guestbook.Models.CommentSummary><table>    <tr>        <th>Number of comments</th>        <th>User name</th>    </tr>    @foreach(var summaryRow in Model)    {        <tr>            <td>@summaryRow.NumberOfComments</td>            <td>@summaryRow.UserName</td>        </tr>    }</table>

2. Online Store example

Let's start with a simple online store example. It may contain the customer, order, and product classes, which correspond to tables in the relational database and map using the object-link Cer.

    public class Customer    {        public int Number { get; set; }        public string FirstName { get; set; }        public string LastName { get; set; }        public bool Active { get; set; }        public ServiceLevel ServiceLevel { get; set; }        public IEnumerable<Order> Orders { get; set; }    }    public enum ServiceLevel    {        Standard, Premier    }    public class Order    {        public DateTime Date { get; set; }        public IEnumerable<Product> Product { get; set; }        public decimal TotalAmount { get; set; }    }    public class Product    {        public string Name { get; set; }        public decimal Cost { get; set; }    }

The management area of a store may contain a customer summary page, which lists each customer and the number of orders.

An optional way to create this UI is to create the screen directly through the domain model. We can retrieve the customer list from the database and pass it to the view. The view traverses the customer list cyclically and constructs a table. When most recent order date (recent order date) is reached in the last column, the view has to traverse the customer's orders set cyclically to obtain the most recent order.

A problem with this method is that it makes the view very complex. To make the view as maintainable as possible, it should be simplified as much as possible, and complicated loops and computing logic should be placed at a higher level for execution. The only thing the view should do is to display the results of this calculation. This can be done by explicitly indicating the view model of the table.

(1) create a view Model

    public class CustomerSummary    {        public string Name { get; set; }        public string Active { get; set; }        public string ServiceLevel { get; set; }        public string OrderCount { get; set; }        public string MostRecentOrderDate { get; set; }    }

(2) Delivery Performance Model

 public class CustomerSummaryController : Controller    {        private CustomerSummaries _customerSummaries = new CustomerSummaries();        public ActionResult Index()        {            IEnumerable<CustomerSummary> summaries = _customerSummaries.GetAll();            return View(summaries);        }    }
public class CustomerSummaries    {        public IEnumerable<CustomerSummary> GetAll()        {            return new[]            {                new CustomerSummary                {                    Active = "Yes",                    Name = "John Smith",                    MostRecentOrderDate = "02/07/10",                    OrderCount = "42",                    ServiceLevel = "Standard"                },                new CustomerSummary                {                    Active = "Yes",                    Name = "Susan Power",                    MostRecentOrderDate = "02/02/10",                    OrderCount = "1",                    ServiceLevel = "Standard"                },                new CustomerSummary                {                    Active = "Yes",                    Name = "Jim Doe",                    MostRecentOrderDate = "02/09/10",                    OrderCount = "7",                    ServiceLevel = "Premier"                },            };        }    }

(3) viewdata. Model
The Controller and view share a viewdataictionary object named viewdata. It has a unique model attribute. When we call return view (summaries) in listing 5.3, viewdata. model is automatically filled with the customersummary Object List, which is ready for display in the view. The model attribute is also strongly typed, so the view knows exactly The expected type, and allows developers to use features such as IDE smart sensing and support variable rename. The razor view engine masks most of the internal mechanisms, making it easy to define model types. The view can use the @ model indicator to describe its model type:

@model IEnumerable<StoreCh05.Models.CustomerSummary>
    <table>        <tr>            <th>Name</th>            <th>Active?</th>            <th>Service Level</th>            <th>Order Count</th>            <th>Most Recent Order Date</th>        </tr>        @foreach (var summary in Model)        {            <tr>                <td>@summary.Name</td>                <td>@summary.Active</td>                <td>@summary.ServiceLevel</td>                <td>@summary.OrderCount</td>                <td>@summary.MostRecentOrderDate</td>            </tr>        }    </table>

Ii. Presentation of user input

A powerful presentation model makes the view easy to use data, and a powerful input model also makes the application easy to use user input. Instead of using the error-prone string key and the request value that you want to match the input element name, we can use ASP. net mvc to use a powerful input model.

1. design the Input Model

The simple form in the figure has two text boxes and a check box. As a feature of an application, this form is also worth serving as a formal representation: A class.

public class NewCustomerInput  {    public string FirstName { get; set; }    public string LastName { get; set; }    public bool Active { get; set; }  }

2. Represent the input model in the view

public class CustomerController : Controller    {        public ViewResult New()        {            return View();        }        public ViewResult Save(NewCustomerInput input)        {            return View(input);        }    }
@model StoreCh052.Models.NewCustomerInput<div>    <form action="@Url.Action("Save")" method="post">        <fieldset>            <div>                @Html.LabelFor(x => x.FirstName)                @Html.TextBoxFor(x => x.FirstName)            </div>            <div>                @Html.LabelFor(x => x.LastName)                @Html.TextBoxFor(x => x.LastName)            </div>            <div>                @Html.LabelFor(x => x.Active)                @Html.CheckBoxFor(x => x.Active)            </div>            <div>                <button name="save">                    Save</button>            </div>        </fieldset>    </form></div>

3. complex models for display and Input

Knowledge Point 5-1: View Model

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.