Where and how is the _ViewStart.cshtml layout file linked?

133,900

Solution 1

From ScottGu's blog:

Starting with the ASP.NET MVC 3 Beta release, you can now add a file called _ViewStart.cshtml (or _ViewStart.vbhtml for VB) underneath the \Views folder of your project:

The _ViewStart file can be used to define common view code that you want to execute at the start of each View’s rendering. For example, we could write code within our _ViewStart.cshtml file to programmatically set the Layout property for each View to be the SiteLayout.cshtml file by default:

Because this code executes at the start of each View, we no longer need to explicitly set the Layout in any of our individual view files (except if we wanted to override the default value above).

Important: Because the _ViewStart.cshtml allows us to write code, we can optionally make our Layout selection logic richer than just a basic property set. For example: we could vary the Layout template that we use depending on what type of device is accessing the site – and have a phone or tablet optimized layout for those devices, and a desktop optimized layout for PCs/Laptops. Or if we were building a CMS system or common shared app that is used across multiple customers we could select different layouts to use depending on the customer (or their role) when accessing the site.

This enables a lot of UI flexibility. It also allows you to more easily write view logic once, and avoid repeating it in multiple places.

Also see this.

Solution 2

In a more general sense this ability of MVC framework to "know" about _Viewstart.cshtml is called "Coding by convention".

Convention over configuration (also known as coding by convention) is a software design paradigm which seeks to decrease the number of decisions that developers need to make, gaining simplicity, but not necessarily losing flexibility. The phrase essentially means a developer only needs to specify unconventional aspects of the application. For example, if there's a class Sale in the model, the corresponding table in the database is called “sales” by default. It is only if one deviates from this convention, such as calling the table “products_sold”, that one needs to write code regarding these names.

Wikipedia

There's no magic to it. Its just been written into the core codebase of the MVC framework and is therefore something that MVC "knows" about. That why you don't find it in the .config files or elsewhere; it's actually in the MVC code. You can however override to alter or null out these conventions.

Solution 3

Just another thought.

If you want to have your own cshtml file as a common template, you can do it this way

Within your _viewstart.cshtml you can mention your common cshtml file.

@{Layout = "~/Views/Shared/_Layout.cshtml";}

Solution 4

The source code is a much better place to look for this than the documentation.

Referencing the MVC 6 code from Github, we have a few files of interest

----update----

Due to source structure changes, the information on how viewstart pages are gathered can now be found in RazorViewEngine.cs look for "GetViewStartPages" function.

----/update----

To answer how they come into play, look at RazorView, Which I believe (because of IView) is tied in to the MVC pipeline. This file has a RenderAsync method that gets called from the MVC pipeline to render the requested view.

RenderAsync makes calls to RenderPage AND THEN RenderLayout (NOTE THE ORDER). The RenderPage first makes calls to deal with viewstart files (note plural, there could be more than one _viewstart file).

So, the information you seek can be obtained from RenderViewStartAsync function in RazorView.cs file under Microsoft.AspNet.Mvc.Razor namespace.

Solution 5

This may add some addt'l info to this question now (2016 ala MVC4, MVC5).

The Razor engine finds and runs the code in _ViewStart.cshtml before any other code which is in the same directory or subdirectory where the _ViewStart.cshtml is found.

Any view can override the Layout property or any of its values.

Just thought I might add a bit more info to show you why it is _ViewStart.

If you get ILSpy and examine the code in the RazorViewEngine (System.Web.Mvc.dll ) you will see that the code itself references that name.

_ViewStart in  System.Web.Mvc.dll

You can see that the RazorViewEngine looks for a file with that name:

razorviewengine code

RazorViewEngine.ViewStartFileName = "_ViewStart";
Share:
133,900

Related videos on Youtube

Kman
Author by

Kman

Mostly .Net oriented, but I find almost all programming languages and scripts interesting.

Updated on July 21, 2022

Comments

  • Kman
    Kman almost 2 years

    Here's the About.cshtml from the default MVC 3 template:

    @{
        ViewBag.Title = "About Us";
    }
    
    <h2>About</h2>
    <p>
         Put content here.
    </p>
    

    I would expect that a reference to the _ViewStart file would be found in the About.cshtml, but clearly it's not.

    I've looked in global.asax and web.config, but I can't find out how the About.cshtml file is "linked" with the layout from the _ViewStart file.

    Everything works as expected, I'd just like to know what's going on under the hood...

  • Kman
    Kman about 12 years
    So it's more or less a "hardcoded" feature of MVC3? I have no need of changing it to another "default" page, just curious of how it was set up. Thank you for sorting it all out :)
  • jim tollan
    jim tollan about 12 years
    Kman- Hardcoded, by convention (choose another 'handle' here :)) - so yes, exactly. glad it cleared the fog
  • Arne Evertsson
    Arne Evertsson over 10 years
    If MVC knows about it, then why doesn't Visual Studio know and point this out to me? If coding by convention means that stuff works as long as you happen not to break the convention it kind of sucks...
  • Umar Farooq Khawaja
    Umar Farooq Khawaja over 10 years
    Not breaking the convention is kind of the point. AKAIK Ruby on Rails also follows this paradigm.
  • shannon
    shannon about 10 years
    +1 Raif. There no point in defending poorly documented "coding by convention". I could say that about any of my backwards code. "What? You didn't expect it to crash when it got to 33? Everyone knows you skip 33." Unfortunately, the documentation gap for ASP.NET MVC is huge. The only MS docs are auto-generated with no internal source summaries.
  • Robert C. Barth
    Robert C. Barth about 10 years
    Convention over configuration doesn't mean you can't change it. There SHOULD be configuration available to be able to specify the name and location of that file. There may very well be, but who knows what it is. People use the "convention over configuration" mantra to cover a multitude of poor decisions in a codebase and it kinda pissed me off as the guy who comes along after-the-fact to maintain their poorly-documented mess that "just works" (but God-forbid you change anything -- you'll spend hours figuring out how you broke everything).
  • Millie Smith
    Millie Smith almost 9 years
    @AidenStrydom I disagree. The accepted answer actually tells me how to use _ViewStart. This answer just talks about a design concept. I came here for information on _ViewStart, not information about why Visual Studio wouldn't tell me anything about _ViewStart.
  • rism
    rism almost 9 years
    @MillieSmith While I'm not suggesting mine should be the accepted answer, it does actually answer the question. The question is not how do i use _ViewStart?. It's Where and how is ViewStart linked?. To which I've replied where: hard coded in the code base and how: by convention. So i haven't just "talked about a design concept". I've actually explicitly answered the question that was asked, but perhaps not the query you had, which is different from the question that was asked.
  • Millie Smith
    Millie Smith almost 9 years
    @rism Fair enough. I'll agree with that.
  • Triynko
    Triynko almost 9 years
    It's not just in your "Views" folder that you might need it. If you add a custom RazorViewEngine in order to organize views into other folders, you have to include the file in the root of those alternate view folders as well. For example, I moved all the Inspinia template views into a folder and ran this in the view engine ViewLocationFormats = ViewLocationFormats.Union(new string[] { "~/Inspinia/ExampleViews/{1}/{0}.cshtml" }).ToArray();. As a result, I had to add a copy of my _ViewStart.cshtml file to "~/Inspinia/ExampleViews", otherwise it was not picked up and no layout was set.
  • Sebastian 506563
    Sebastian 506563 about 8 years
    this is what I was looking for, I hate "do not know" what is going on in my project, becouse I am also doing my own templates for VS and this file that just come out from air was very unhandy to understand
  • toddmo
    toddmo almost 7 years
    If your Views folder has subfolders, can you put a _ViewStart in each subfolder that will link to the views in that subfolder?