The @model Directive
Declaring @model MyApp.Models.ProductViewModel at the top of a .cshtml file makes that view strongly typed: the Model property inside the view is now statically typed as ProductViewModel rather than the untyped dynamic object a view without @model would have. This single declaration is what enables the Razor editor to offer IntelliSense for @Model.Name or @Model.Price, and it's what allows lambda-based helpers like Html.TextBoxFor(m => m.Name) to compile, since the compiler needs to know the concrete type to resolve the property access.
Cricket analogy: Like a scorecard template pre-printed with named columns for 'runs', 'balls', and 'strike rate' instead of a blank sheet, @model MyApp.Models.ProductViewModel gives the view a known, structured shape instead of an untyped, freeform object.
View Models vs Domain Entities
A view model is a class shaped specifically for what a single view needs to display or collect, distinct from a domain entity like a Product Entity Framework class, which is shaped around persistence concerns and may carry navigation properties, database-only fields, or validation rules irrelevant to a particular screen. Passing a view model, such as ProductEditViewModel with just Name, Price, and a SelectList of Categories, instead of the raw Product entity, avoids leaking internal database structure to the view and lets you tailor data annotations like [Required] specifically to what that form actually needs.
Cricket analogy: Like a broadcaster's on-screen graphic showing only strike rate and boundary count, a curated subset relevant to viewers, rather than the full raw scoring database with every delivery's metadata, a view model exposes only what a screen needs, not the full domain entity.
// ViewModels/ProductEditViewModel.cs
public class ProductEditViewModel
{
public int Id { get; set; }
[Required(ErrorMessage = "Product name is required")]
[StringLength(100)]
public string Name { get; set; }
[Range(0.01, 10000)]
public decimal Price { get; set; }
public int SelectedCategoryId { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
}
// Edit.cshtml
@model MyApp.ViewModels.ProductEditViewModel
@using (Html.BeginForm())
{
@Html.HiddenFor(m => m.Id)
@Html.LabelFor(m => m.Name)
@Html.TextBoxFor(m => m.Name)
@Html.ValidationMessageFor(m => m.Name)
@Html.DropDownListFor(m => m.SelectedCategoryId, Model.Categories)
<button type="submit">Save</button>
}Why Compile-Time Checking Matters
Because the view is bound to a concrete class, referencing a property that doesn't exist, such as @Model.Naem, or that has been renamed since the view was written produces a build error rather than a runtime NullReferenceException discovered only when a user hits that page in production. This is the central practical advantage strongly typed views have over untyped views that would rely on dynamic ViewBag-style access for the same data: a rename or a typo becomes visible during development, in code review, or in a CI build, well before it can reach an end user.
Cricket analogy: Like a pre-match pitch inspection catching a dangerous crack before play starts rather than a batter discovering it mid-innings, compile-time checking on a strongly typed view catches a typo'd property before a user ever hits that page.
Use @model IEnumerable<ProductSummaryViewModel> for a view rendering a list, and iterate with @foreach (var item in Model). For master-detail scenarios, a dedicated composite view model containing both the list and any filter/paging state is usually cleaner than passing multiple loosely related objects via ViewBag.
Avoid passing Entity Framework entities directly to views when the view also needs to render form inputs for editing — doing so risks over-posting attacks, where a malicious client submits extra form fields that bind to sensitive entity properties (like IsAdmin) that the view never intended to expose. A dedicated view model with only the intended editable fields prevents this.
- The @model directive at the top of a .cshtml file binds the view's Model property to a specific C# type.
- Strongly typed views enable IntelliSense and compile-time checking for @Model.Property references in the editor.
- View models are shaped for a specific screen's needs, distinct from domain/EF entities shaped for persistence.
- Passing view models instead of raw entities avoids leaking database structure and helps prevent over-posting attacks.
- Lambda-based helpers like Html.TextBoxFor(m => m.Name) require a strongly typed model to compile at all.
- A renamed or misspelled model property produces a build error in a strongly typed view instead of a runtime failure.
Practice what you learned
1. What does declaring @model MyApp.Models.ProductViewModel at the top of a view do?
2. Why is a dedicated view model often preferred over passing a raw Entity Framework entity to a view?
3. What is required for a lambda-based helper like Html.TextBoxFor(m => m.Name) to compile?
4. What happens if a property referenced in a strongly typed view, like @Model.Naem, doesn't exist on the model class?
5. What is an over-posting attack?
Was this page helpful?
You May Also Like
HTML Helpers
Learn how HtmlHelper extension methods generate form controls, links, and validation markup in Razor views, and how they differ from raw HTML.
ViewBag, ViewData, and TempData
Compare the three loosely typed ways ASP.NET MVC passes data from controllers to views and across redirects, and when each one is appropriate.
The Razor View Engine
Understand how Razor compiles .cshtml templates into C# classes, its @ syntax, encoding rules, and how it fits into the ASP.NET MVC request pipeline.
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesWindows Batch Scripting Study Notes
Batch · 30 topics
Microsoft TechnologiesMFC (Microsoft Foundation Classes) Study Notes
C++ · 30 topics
Microsoft TechnologiesSilverlight Study Notes
.NET · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesWPF (Windows Presentation Foundation) Study Notes
.NET · 30 topics