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


