C# – the execution order of an MVC Razor view/layout

asp.net-mvc-3crazor

I have a razor layout like:

@using (var context = SetUpSomeContext()) {
    <div>
        Some content here
        @RenderBody();
    </div>
}

And a view like:

@{
    Layout = "MyLayout.cshtml";
}
<div>@SomethingThatDependsOnContextBeingSetUp()</div>

When the view renders, SomethingThatDependsOnContextBeingSetUp executes before SetUpSomeContext and fails. This seems weird, because I would expect that not to execute until RenderBody is called in the layout. When I switch this to use a "PageContent" section instead of RenderBody, everything works as expected. Can anyone explain this behavior?

Best Answer

The Razor pipeline is:

  1. First, Razor evaluates, if present, _ViewStart.cshtml that contains only Razor statements (C# or VB) for assign Layout or other initialization, it should never have html tags inside.

  2. Then, it parse and evaluates the "View" cshtml file.

  3. Then, it parse and evaluates, if present, the Layout, and when evaluates the @RenderBody method of the cshtml layout file, replaces it with the html script resulting from evaluation of "View" cshtml file.

  4. Finally, it builds the html control graph objects of layout and view html files.


So, you cannot do depend any "Razor" objects of a view from layout operations, but rather you may put in _ViewStart.cshtml your initialization of objects visible to your view.


You may imagine cs(vb)html views as a static content loaded when Controller.View method is called.

At that point, the cshtml loaded content is parsed by Razor that evaluates the expressions (assign properties(as Layout), branchs, loops) and build a sort of binary tree or graph of "HtmlControls" objects into the ActionResult object returned by View method.

Next, ActionResult is rendered as html from Asp.Net and returned to the client as http response.

To do that, Razor parses cshtml files and carries out their code inside parts starting first from the "_ViewStart.cshtml" (also more of one if present in the sub folders chain related to the origin controller), then follows cshtml file loaded by conventions (name of view equals to the name of action in the path Views/[ControllerName]/), or by expressed view's name as parameter when calling View method, and finally, the eventual layout file linked to the view by Layout property.