开发者

Override the Default ViewEngine to Look in Different Directories

I created an area in Visual Studio which automatically adds the appropriate bits in the "Areas" directory. I renamed this to "Modules" but now when i navigate to /{area}/{controller/{action} it still looks for the view within the /Areas/{area}/Views/{controller/{action} directory and not the /Modu开发者_Python百科les/{area}/Views/{controller/{action} directory. I would also like to be able to override the view for specific themes. Therefore i was wondering how i could customise the default view engine to look for the view in the following locations aswell:

  • /Themes/Default/Views/{area}/{controller}/{action}.cshtml
  • /Modules/{area}/Views/{controller}/{action}.cshtml

I'd really appreciate it if someone could help.

Thanks


As ASP.NET MVC source code is available, it is easy to answer these kinds of questions by looking at the source. If you look at the WebFormViewEngine class you can see the locations listed and it will be easy for you to inherit from this and customise them.

However, not going with the code by convention approach is just going to make your life harder so I'd advise living with the default locations.


Here's the code incase anyone is interested:

public class CustomRazorViewEngine : RazorViewEngine {
    public CustomRazorViewEngine()
        : this(null) {
    }

    public CustomRazorViewEngine(IViewPageActivator viewPageActivator)
        : base(viewPageActivator) {
        AreaViewLocationFormats = new[] {
            "~/Themes/Default/Views/{2}/{1}/{0}.cshtml",
            "~/Themes/Default/Views/{2}/Shared/{0}.cshtml",
            "~/Modules/{2}/Views/{1}/{0}.cshtml",
            "~/Modules/{2}/Views/Shared/{0}.cshtml"
        };
        AreaMasterLocationFormats = new[] {
            "~/Themes/Default/Views/{2}/{1}/{0}.cshtml",
            "~/Themes/Default/Views/{2}/Shared/{0}.cshtml",
            "~/Modules/{2}/Views/{1}/{0}.cshtml",
            "~/Modules/{2}/Views/Shared/{0}.cshtml"
        };
        AreaPartialViewLocationFormats = new[] {
            "~/Themes/Default/Views/{2}/{1}/{0}.cshtml",
            "~/Themes/Default/Views/{2}/Shared/{0}.cshtml",
            "~/Modules/{2}/Views/{1}/{0}.cshtml",
            "~/Modules/{2}/Views/Shared/{0}.cshtml"
        };
    }
}

Now just place the following in the Application_Start event in the Global.asax.cs file:

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomRazorViewEngine());

Hope this helps.


The code you posted is very similar to what I wound up doing a few months ago.

I also have a preprocessing step (run on-demand or at compile time) which finds all of the .cshtml files in the site folder hierarchy and adds their relative paths to a table in the database. The site caches that data on startup. The custom view engine then searches that list for views, and only checks the disk when it finds a match.

This performs very, very well. Avoiding disk access will probably only help if you're running a very busy site. Even though disk access is very slow, it's typically not a performance bottleneck and ASP.NET performs its own intelligent caching.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜