Razor View File Locations

At this point, you may be wondering just how ASP.NET MVC is able to match the name of a view to its physical location in the filesystem. For that matter, how does ASP.NET MVC differentiate between two views that share the same file name, yet reside in different folders? The answer to both of these questions is the same: the Razor View Engine!

When a controller action returns a ViewResult, ASP.NET MVC knows that it needs to render a view, so it asks all of its registered view engines if they can figure out how to locate and render the requested view. Between the routing information for the current request and the ViewResult, the view engines should have all the information they need: the view name and the name of the controller that handled the request. By convention, all ASP.NET MVC views live in subfolders under the ~/Views folder.

In one of the previous examples, the HomeController requested the view named Index. Let’s see how the Razor View Engine tries to locate the Index view.

Controller Views

The first place the Razor View Engine will look for a view is in the folder with the same name as the controller that handled the request. Given the request from the HomeController for the Index view, the view engine will check if the C# Razor template ~/Views/Home/Index.cshtml exists. If not, the engine tries again, this time looking for the VB.NET Razor template named ~/Views/Home/Index.vbhtml. Though C# and VB.NET are the only languages Razor currently supports, the same process would apply for any new languages that might be added (for example, the engine might look for ~/Views/Home/Index.fshtml for an F# template if such an implementation existed).

When the view engine locates a file, it stops looking immediately and returns the first file it found. Otherwise, it continues down its list of search paths to look in the Shared folder.

Locating Razor Views

Armed with all the information about the controller that handled the current request, the Razor View Engine relies on the default view locator logic to build a list of possible locations in which the requested view may reside. After compiling this list, the view engine simply iterates over it, returning the first match it finds. As you might expect, the view engine prefers more specific views—views defined in the folder with the same name as the Controller that requested them—over views in the Shared folder, so the more specific views will appear higher on the list than shared views.

This example illustrates this point, showing what the list of possible view locations might look like in order to locate a request for the Index view that generated from a controller named HomeController:

The view engine’s view candidates
~/Views/Home/Index.cshtml
~/Views/Home/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml

Thus, if the ~/Views/Home/Index.cshtml view exists, the view engine will choose it and ignore the rest of the list. If, however, ~/Views/Home/Index.cshtml does not exist, but ~/Views/Shared/Index.cshtml exists instead, the view engine will continue searching down the list, checking each entry, until it discovers that ~/Views/Shared/Index.cshtml is valid and chooses it.

Shared Views

You may have noticed that the folder list includes references to the Shared folder. The ~/Views/Shared folder contains views that can be reused by multiple controllers. The Shared folder is created along with the rest of the initial application artifacts by the ASP.NET MVC website template and initially contains the basic layout and error-handling views (_Layout.cshtml and Error.cshtml, respectively), two perfect examples of reusable views.

Views in ASP.NET MVC Areas

The Areas feature of ASP.NET MVC allows a web application to be split up into multiple sections (“Areas”), enabling developers to work on each section individually in relative isolation. Though an in-depth discussion of ASP.NET MVC Areas would be outside the scope of this book, Areas are effectively a “website within a website” and, as such, it is worth discussing how Areas affect the views that are created within them.

For example, let’s add an Area named “Administration” to the demo blog site. To add an Area, right-click on the ASP.NET MVC project and select the Add... context menu option, which should pop up the submenu shown in Figure 4-5 and specify the Area name “Administration” when prompted.

Add Area context menu option

Figure 4-5. Add Area context menu option

As Figure 4-6 shows, ASP.NET MVC Areas define a folder structure within the main website that follows the same standard Controllers, Models, and Views convention. The primary difference is that the root folder of this structure is not the root folder of the ASP.NET MVC application.

Website folder structure with an Area

Figure 4-6. Website folder structure with an Area

Since Areas use the same folder structure convention, the only significant change they introduce in regard to Views is adding their folders to the list of search folders that the View Engine uses to locate the correct view. For example, a ViewResult from an action within the Administration Area’s DashboardController would modify a default search folder list:

~/Views/Dashboard/Index.cshtml
~/Views/Dashboard/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml

to include the Views folder within the Admin area:

~/Areas/Administration/Views/Dashboard/Index.cshtml
~/Areas/Administration/Views/Dashboard/Index.vbhtml
~/Areas/Administration/Views/Shared/Index.cshtml
~/Areas/Administration/Views/Shared/Index.vbhtml
~/Views/Dashboard/Index.cshtml
~/Views/Dashboard/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml

Outside of the modified search path, developing views within Areas is the same as developing views located in the main website.

Tip

The way the Razor View Engine and the Web Forms View Engine look for views is almost exactly the same. Both engines look in the folder with the name of the current controller as well as the Shared folder. Both engines also respect the Areas folder as well. In fact, the primary difference in the way the two view engines locate views is the file extension they’re looking for: the Razor View Engine searches for .cshtml and .vbhtml files while the Web Forms View Engine searches for files with the .aspx and .ascx extensions.

Get Programming Razor now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.