liveBook · Manning

View model

As explained in ASP.NET Core in Action, 3e

A view model is an object or data structure containing the information a user-interface view requires to render a response.

A view model holds the data a view needs to render a UI. It is usually shaped from application data and may include display details, such as a page title. The handler or controller supplies that data; the view decides how to turn it into HTML. section 13.4.3 section 13.3

The data reaches a Razor view differently in two ASP.NET Core approaches:

  • In Razor Pages, a handler sets properties on the PageModel. The associated Razor view reads those properties, so the PageModel typically serves as the view model. section 13.4.3
  • In MVC controllers, an action passes a separate object to View(). The resulting ViewResult carries the model to the selected Razor view. section 19.2 section 19.4

An error page

An MVC action can return View(new ErrorViewModel { RequestId = ... }). Its Razor view declares @model ErrorViewModel, then uses Model.ShowRequestId to decide whether to display Model.RequestId. The action provides the data; the view controls the markup. section 19.2 section 19.4

A view model need not mirror a database entity. For a recipe list, RecipeSummaryViewModel contains an ID, name, and display-ready cooking time. An EF Core LINQ Select projection creates those objects while fetching only the needed columns. Building the view model in an endpoint handler instead of the service is also an option; keep entities out of the endpoint’s public API. section 12.4.2

Listing 12.7 Loading a list of items using EF Core in RecipeService
public async Task<ICollection<RecipeSummaryViewModel>> GetRecipes()
{
    return await _context.Recipes                              #1
        .Where(r => !r.IsDeleted)
        .Select(r => new RecipeSummaryViewModel                #2
        {                                                      #2
            Id = r.RecipeId,                                   #2
            Name = r.Name,                                     #2
            TimeToCook = $"{r.TimeToCook.TotalMinutes}mins"    #2
        })
        .ToListAsync();                                        #3
}
#1 A query starts from a DbSet property.
#2 EF Core queries only the Recipe columns it needs to map the view model correctly.
#3 Executes the SQL query and creates the final view models

Follow the query from filtering recipes through projecting each row into a RecipeSummaryViewModel and executing it with ToListAsync(). section 12.4.2

Do not confuse this MVC use of “view model” with two-way binding in Model-View-ViewModel (MVVM). A Razor Pages PageModel can supply view data without making Razor Pages an MVVM implementation. section 13.4

How ASP.NET Core in Action, 3e covers it

How deep it goes
Defines rendering data and works through PageModel properties, ViewResult delivery, and an EF Core projection.
Examples
Uses an error page’s request ID and a projected list of recipe summaries.
What you can do after
Apply it via MVC’s View(model) or Razor Pages’ PageModel properties to provide rendering data to a Razor view.
How it connects
Connects MVC, Razor Pages, PageModel, Razor views, ViewResult, and EF Core queries.

Also explained in

Compare how 3 books explain view model →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of ASP.NET Core in Action, 3e. The section links point to the parts of the book it draws on.