Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is a full path to layout required in viewstart file when locations are specified in the view engine?

I am playing with the razor view engine and there's something I don't quite get.

The _ViewStart file specifies a layout with the full file path like this:

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

As I understand it, the full path and extension must be included. You can't just do this:

@{
    Layout = "_MasterLayout";
}

However the view engine specifies locations to search for the master views:

        MasterLocationFormats = new string[] { 
            "~/Views/{1}/{0}.cshtml",
            "~/Views/Shared/{0}.cshtml"
        };

How come the full path to the master layout file is required in the _ViewStart file?

And if the full path is specified, what is the point of then specifying possible locations in MasterLocationFormats[]?

Update

Well I still haven't found a satisfactory answer to this.

From experimenting it would appear that the MasterLocationFormats are either ingored or overridden when specifying a Layout in the viewstart file.

I could completely remove the MasterLayout.cshtml location from the MasterLocationFormats and it didn't make any difference to the display of web pages.

My personal question was due to using the MvcMailer package, which allows you to specify a razor view to use as a template for sending html email. This DOES use the MasterLocationFormats.

So I'm still a bit perplexed, but hope this will be of some use to anybody coming here. Also , this post may also be of help.

like image 916
Martin Hansen Lennox Avatar asked Oct 21 '22 14:10

Martin Hansen Lennox


1 Answers

In CreateView implementation of RazorViewEngine a new RazorView is created.

And when RazorView overrides RenderView method of BuildManagerCompiledView which makes the actual call to Render method of IView.

And at the end of this implementation that line is called.

webViewPage.ExecutePageHierarchy(new WebPageContext(context: viewContext.HttpContext, page: null, model: null), writer, startPage);

And that leads us to ExecutePageHierarchy method of WebViewPage which is in System.Web.Mvc.dll.

public override void ExecutePageHierarchy()
{
    TextWriter writer = this.ViewContext.Writer;
    this.ViewContext.Writer = this.Output;
    base.ExecutePageHierarchy();
    if (!string.IsNullOrEmpty(this.OverridenLayoutPath))
        this.Layout = this.OverridenLayoutPath;
    this.ViewContext.Writer = writer;
}

As you can see above Layout path is overriden.

For more information, you can check RazorView and WebViewPage classes.

like image 130
Ömer Cinbat Avatar answered Nov 22 '22 21:11

Ömer Cinbat