A view model is the data an ASP.NET Core MVC action supplies to a Razor view for rendering HTML. The action constructs or selects the data and passes it to `View(...)`; the view decides how to display it. The view does not need to know where the data came from. section 2.3.3 section 7.3.2
Pass a value into a view
An action can return `View("MyView", greeting)`, where `greeting` is a string. In `MyView.cshtml`, `@model string` declares the expected type, and `@Model` inserts the supplied value into the HTML. The lowercase `m` declares the type; the uppercase `M` reads the value. A request then produces different HTML depending on the greeting chosen by the action. section 2.3.3 section 2.3.4
The value need not be a string. A view can declare `@model GuestResponse` and read a property with `@Model.Name`; a form can use `asp-for="Name"` to associate a label or input with that property. In an RSVP flow, a model-bound `GuestResponse` becomes the Thanks view’s model, so its name and attendance choice determine the response. section 3.2.5 section 3.2.7
For a list, the action can pass product objects and the view can use `@foreach` to render each one. Razor model data can be null even when `@model` names a non-nullable type, so a collection view can fall back to `Enumerable.Empty<Product>()`. Declaring the view model type also lets code expressions in the view be type-checked. section 7.3.2 section 21.5
When one page needs several kinds of data, define a view-model class for that page rather than forcing the view to obtain the missing pieces. A paged catalog uses `ProductsListViewModel` to carry both `Products` and `PagingInfo`. The action fills them from the repository and paging parameters; the view renders products and gives the paging information to a page-link tag helper. section 7.4.1
Listing 7.30 The contents of the ProductsListViewModel.cs file in the SportsStore/Models/ViewModels folder
namespace SportsStore.Models.ViewModels {
public class ProductsListViewModel {
public IEnumerable<Product> Products { get; set; }
= Enumerable.Empty<Product>();
public PagingInfo PagingInfo { get; set; } = new();
}
}
The class shows a page-specific view model combining product data with pagination data. section 7.4.1
Listing 7.33 Adding the pagination links in the Index.cshtml file in the SportsStore/Views/Home folder
@model ProductsListViewModel
@foreach (var p in Model.Products ?? Enumerable.Empty<Product>()) {
<div>
<h3>@p.Name</h3>
@p.Description
<h4>@p.Price.ToString("c")</h4>
</div>
}
<div page-model="@Model.PagingInfo" page-action="Index"></div>
The Razor view reads the product collection and passes `PagingInfo` to the page-link tag helper. section 7.4.1
A view model can also carry form state that must survive a request. A login view model holds credentials and a return URL; the login view binds form fields to its properties, including a hidden field for the return URL. Validation and authentication remain separate concerns: the view model supplies the values used by the form and action. section 11.4


