ASP.NET MVC Razor pass model to layout
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In ASP.NET MVC, a layout page wraps many views, so it often needs shared data such as page title, navigation state, or user information. The mistake many developers make is trying to pass each view’s full model directly into the layout, which couples unrelated pages to one layout contract. The maintainable solution is giving the layout only the shared data it actually needs.
Understand the Layout Boundary
A Razor view can be strongly typed with @model, but the layout does not automatically get a second independent model. The layout is rendered as part of the same view pipeline, so if it accesses Model, it sees the child view’s model type.
That means this is fragile:
inside the layout, because not every child view uses ProductDetailsViewModel.
If different pages have different models, the layout should not depend on a concrete page-specific type.
Use ViewBag or ViewData for Small Shared Values
For a few simple layout values such as title or current section, ViewBag or ViewData is usually enough.
Controller:
Layout:
This is simple and works well for lightweight layout metadata.
Use a Dedicated Layout View Model for Rich Shared State
If your layout needs structured data such as notification counts, menu items, or signed-in user details, create a dedicated layout model and expose it separately instead of reusing page models.
Shared layout model:
Then attach it to ViewBag or ViewData:
Layout:
This keeps page models and layout concerns cleanly separated.
Use Child Actions or Shared Components for Repeated Layout Data
If the layout needs dynamic data from services on every request, avoid duplicating controller code everywhere. In classic ASP.NET MVC, a common pattern is a child action or shared partial.
Controller:
Layout:
This is often cleaner when layout data is assembled from authentication state or shared services.
Avoid Passing Full Page Models to the Layout
Trying to make the layout strongly typed to every view model usually creates one of two problems:
- the layout becomes tied to one page type
- developers fall back to unsafe casting and null checks everywhere
If the layout needs a value from page models across many pages, that is often a signal to extract a smaller shared abstraction instead.
A simple approach is creating a base page view model:
This can work, but keep the shared base focused and small.
Common Pitfalls
One common mistake is assuming the layout can safely declare its own unrelated @model type. Another is placing too much business data in ViewBag, which becomes hard to discover and test. Developers also duplicate the same layout setup code across many controllers instead of centralizing it. Finally, casting page-specific models inside the layout makes the layout brittle and tightly coupled to individual screens.
Summary
- A Razor layout sees the child view model, not a separate layout model automatically.
- Use
ViewBagorViewDatafor small shared layout values. - Use a dedicated layout view model for richer shared layout state.
- Centralize repeated layout data building with shared controller logic or partial rendering.
- Do not couple layouts to page-specific models unless every page truly shares that type.
- Keep layout contracts narrow so page views and shared chrome evolve independently.

