100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
.NET Framework

Strongly Typed Views

Learn how the @model directive binds a Razor view to a specific C# class, enabling IntelliSense, compile-time checking, and clean use of lambda-based helpers.

Views and RazorBeginner8 min readJul 10, 2026
Analogies

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.

csharp
// 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

Was this page helpful?

Topics covered

#NETFramework#ASPNETMVCStudyNotes#MicrosoftTechnologies#StronglyTypedViews#Strongly#Typed#Views#Model#StudyNotes#SkillVeris