ASP.NET MVC · Controllers & Views

Views

A view is the HTML template for one page. Knowing exactly where MVC looks for it saves you from the most common beginner error message in MVC.

Beginner 5 min Lesson 8 of 37Covers ASP.NET MVC 5.2 on .NET Framework 4.8.
Before you start:Action Methods
0/37 in ASP.NET MVC
On this page · 5 min · Beginner

Learning objectives#

  • Explain the view lookup order
  • Render a view with a different name or path
  • Share views through Views/Shared
  • Pass a model to a view

Explanation#

return View() renders the view named after the action. MVC searches ~/Views/{Controller}/{Action}.cshtml, then ~/Views/Shared/{Action}.cshtml (plus .vbhtml versions).

return View("Summary") renders a view with another name, searched in the same folders. return View("~/Views/Reports/Monthly.cshtml") uses an exact path.

Views in Views/Shared can be used by every controller — useful for Error.cshtml, layouts, partials and common pages.

return View(model) passes data to the view; inside it, the Model property holds it. View("Name", model) does both.

If no file is found, MVC throws InvalidOperationException listing every location it searched — read that list to find the typo.

Syntax#

C# Illustrative
return View();                                   // Views/Products/Index.cshtml
return View("Summary", model);                   // Views/Products/Summary.cshtml
return View("~/Views/Reports/Monthly.cshtml");    // exact path
return View("Maintenance");                      // falls back to Views/Shared

Code example: Same controller, different views#

C#ReportsController.cs Illustrative
// Controllers/ReportsController.cs
using System.Web.Mvc;


namespace ShopSite.Controllers
{
    public class ReportsController : Controller
    {
        // Views/Reports/Index.cshtml
        public ActionResult Index()
        {
            return View();
        }


        // Views/Reports/Summary.cshtml, with a model
        public ActionResult Today()
        {
            return View("Summary", 12450.75m);
        }


        // Not in Views/Reports, so MVC uses Views/Shared/Maintenance.cshtml
        public ActionResult Yearly()
        {
            return View("Maintenance");
        }


        // A view that does not exist anywhere
        public ActionResult Broken()
        {
            return View("Nope");
        }
    }
}


@* Views/Reports/Index.cshtml *@
<h1>Reports</h1>


@* Views/Reports/Summary.cshtml *@
@model decimal
<h1>Today’s sales</h1>
<p>@Model.ToString("N2") rupees</p>


@* Views/Shared/Maintenance.cshtml *@
<h1>This report is being updated</h1>
<p>Please try again later.</p>
Expected output
GET /Reports
200 OK
<h1>Reports</h1>

GET /Reports/Today
200 OK
<h1>Today’s sales</h1>
<p>12,450.75 rupees</p>

GET /Reports/Yearly
200 OK
<h1>This report is being updated</h1>
<p>Please try again later.</p>

GET /Reports/Broken
500 Internal Server Error

This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.

Step-by-step explanation#

  1. Index returns View(), so MVC renders Views/Reports/Index.cshtml.
  2. Today renders the Summary view with a decimal model; @model decimal makes Model a decimal, formatted with N2.
  3. Yearly asks for Maintenance, which only exists in Views/Shared, so MVC uses it after checking Views/Reports.
  4. Broken asks for a view that does not exist: the exception becomes a 500, and with custom errors on the user sees the Error page.

Real-world use case#

An admin area shows a friendly “This section is under maintenance” page from five different controllers during a data migration — one view in Views/Shared, returned with View("Maintenance").

Common mistakes#

Mixing up View("Name") and View(model) with a string model

return View(message) where message is a string treats it as a view name, not a model. Use View((object)message) or View("Index", model: message).

Saving the view with the wrong Build Action

If a .cshtml file is set to Build Action: None, it is not published and works locally but fails on the server. Keep it as Content.

Ignoring the searched-locations list

The error lists every path MVC tried. Comparing it with your file name usually reveals a typo or wrong folder within seconds.

Best practices#

  • Keep one folder per controller
  • Use Views/Shared for anything reused across controllers
  • Name views after actions so View() just works
  • Use full paths only for unusual cases

Remember this#

Views/{Controller}/{Action}.cshtml, then Views/Shared.

View("Name", model) picks both.

Missing view → error lists every location searched.

Practice exercise#

Your task: Create a shared view NotReady.cshtml and return it from two different controllers’ actions, passing the feature name as the model.

Need a hint?
Use View("NotReady", (object)"Gift cards") so the string is treated as a model.
Show solution
C# Illustrative
// Controllers/GiftCardsController.cs
using System.Web.Mvc;


namespace ShopSite.Controllers
{
    public class GiftCardsController : Controller
    {
        public ActionResult Index() => View("NotReady", (object)"Gift cards");
    }


    public class WishlistController : Controller
    {
        public ActionResult Index() => View("NotReady", (object)"Wishlist");
    }
}


@* Views/Shared/NotReady.cshtml *@
@model string
<h1>@Model is coming soon</h1>
Expected output
GET /GiftCards
200 OK
<h1>Gift cards is coming soon</h1>

GET /Wishlist
200 OK
<h1>Wishlist is coming soon</h1>

Mini quiz#

Views quizMultiple choice Question 1 of 3

After Views/Orders/Track.cshtml, where does MVC look for the Track view of OrdersController?

Score so far: 0/0

Want more? Practise all ASP.NET MVC MCQs · ASP.NET MVC interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.