ASP.NET MVC: Multiple View Folders and _ViewStart.cshtml file
Asked Answered
B

2

5

I have an MVC project that requires there to be 2 different View folders. One is at ~/Views/ and one at ~/Framework/Views/. This is done by creating a custom view engine based on the razor view engine like this:

public class MyViewEngine : RazorViewEngine
{
    private static string[] AdditionalViewLocations = new[]{
        "~/Framework/Views/{1}/{0}.cshtml",
        "~/Framework/Views/{1}/{0}.vbhtml",
        "~/Framework/Views/Shared/{0}.cshtml",
        "~/Framework/Views/Shared/{0}.vbhtml"
    };

    public MyViewEngine()            
    {
        base.PartialViewLocationFormats = base.PartialViewLocationFormats.Union(AdditionalViewLocations).ToArray();
        base.ViewLocationFormats = base.ViewLocationFormats.Union(AdditionalViewLocations).ToArray();
        base.MasterLocationFormats = base.MasterLocationFormats.Union(AdditionalViewLocations).ToArray();
    }
}

The problem is that I want to use a different _ViewStart.cshtml file in each of the 2 Views folder (i.e. ~/Views/_ViewStart.cshtml for views found in the ~/Views/ folder and ~/Framework/Views/_ViewStart.cshtml for views found in the ~/Framework/Views/ Folder), however the View Engine just uses the first one it finds which is the original one in ~/Views/.

Is this possible to do?

Thank you

Beverly answered 7/3, 2013 at 22:15 Comment(3)
Why not use Areas instead of messing with view engine?Rodarte
This is definitely possible - in fact I just whipped it up on my machine using the view engine you supplied, just copied and pasted. I am not seeing the same behavior as you. I have two _ViewStart files, one at ~/Framework/Views/_ViewStart.cshtml, and one at ~/Views/_ViewStart.cshtml. When I run a view within ~/Framework/Views/, it uses the Framework _ViewStart. When I run a view within ~/Views/, it uses the _ViewStart there. Double checking the code in RazorViewEngine using DotPeek also confirms that this is how it should behave. Are you sure you aren't missing something?Tetrarch
@NickAceves: Thanks you're right. My file was saved in the wrong location and a duplicate of the wrong file was saved in the right location! What a dooch! Thanks again. (put it in an answer and I'll mark it)Beverly
T
7

This is definitely possible, I think you just missed something.

I have tested this myself using the view engine you supplied (copied and pasted verbatim). I am not seeing the same behavior as you. I have two _ViewStart.cshtml files, one at ~/Framework/Views/_ViewStart.cshtml, and one at ~/Views/_ViewStart.cshtml.

When I run a view within ~/Framework/Views/, it uses the _ViewStart.cshtml in the Framework folder. When I run a view within ~/Views/, it uses the _ViewStart.cshtml in the Views folder.

Double checking the code in RazorViewEngine using DotPeek also confirms that this is exactly how it should behave. The view engine starts checking in for a file named _ViewStart.cshtml within the same folder as the view being rendered, and then walks up the directory tree until it gets to the root of the application.

Tetrarch answered 9/3, 2013 at 1:49 Comment(0)
H
3

The selection of _ViewStart is hierarchical, but you've added ~/Framework/Views parallel to ~/Views. I don't think Razor is set up to actually do what you want (i.e. two completely parallel view locations). If you were to put Framework into the main Views folder, your _ViewStarts would load properly, though.

Haff answered 7/3, 2013 at 22:29 Comment(4)
I see yes. So would the framework directory be something like this: ~/Views/Framework/_ViewStart.cshtml and ~/Views/Framework/Controller/Action.cshtml. And is the custom razor view engine then still needed but changing the AdditionalViewLocations to something like this: "~/Views/Framework/{1}/{0}.cshtml"?Beverly
Or is that still parallel view locations? Should I just add the Framework folder as an area? (Haven't used areas before, so sorry if I'm misunderstanding)Beverly
No, that's exactly what I'm talking about. If you put all your "Framework" views together in a folder and put a _ViewStart in that folder, then it will apply to everything at that level and below. Think of it as an override. You would no longer need a custom razor engine.Haff
As for areas, that's a perfectly acceptable approach as well. Areas have their own Views folder, but they still look in the main Views folder as well. So you could have a "Framework" area, and put a _ViewStart in the ~/Areas/Framework/Views folder.Haff

© 2022 - 2024 — McMap. All rights reserved.