asp.net mvc 3, Themes (different Views)

2019-05-18 19:17发布

问题:

I want to add themes to my site that will use totally different Views. I want to see them in my project like this:

Views/Theme1/...
Views/Theme2/...

instead of default

Views/...

And of coz I need a simple way to switch between them.

So the question is: how can I make ViewEngine to look for Views in a specific place mentioned, for example, in web.config?

Added

Solved the base problem with this, thx to Archil:

public class ThemedRazorViewEngine : RazorViewEngine
{
    public ThemedRazorViewEngine(string themeName)
    {
        MasterLocationFormats = new string[] { "~/Views/" + themeName + "/Shared/{0}.cshtml" };
        PartialViewLocationFormats = new string[] { "~/Views/" + themeName + "/{1}/{0}.cshtml" };
        ViewLocationFormats = new string[] { "~/Views/" + themeName + "/{1}/{0}.cshtml" };
    }
}

Everything good, but "right click - > go to view" doesn't work any more (side effect, no big deal).

And now I came up with another question: on web site we have administration panel that should be theme independent ofc. How can I fix that? to have something like this:

Views/Admin/...
Views/Theme1/...
Views/Theme2/...

回答1:

Simplest solution for theme value in web.config is to create custom ViewEngine and override only view search locations. This way you dont have to change anything in Controller (Example uses only cshtml files for c# only view engine, you have to add vbhtml extensions if you want to use visual basic views)

public class ThemedRazorViewEngine : RazorViewEngine
{
    public ThemedRazorViewEngine(string themeName)
    {
        AreaMasterLocationFormats = new string[] { "~/Areas/{2}/Views/ " + themeName + "/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/" + themeName + "/{0}.cshtml" };

        //and same for all of below
        AreaPartialViewLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" };
        AreaViewLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" };
        FileExtensions = new string[] { "cshtml" };
        MasterLocationFormats = new string[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" };
        PartialViewLocationFormats = new string[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" };
        ViewLocationFormats = new string[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" };
    }
}

And registration of view engine

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new ThemedRazorViewEngine(ConfigurationManager.AppSettings["currentTheme"]));


回答2:

how can I make ViewEngine to look for Views in a specific place mentioned.

You need to give the path in the View method:

return View("~/Views/Theme1/Index");
return View("~/Views/Theme2/Index");

And for the web.config example:

var themeFromWebConfig = GetThemeFromWebConfig();
var viewName = "~/Views/" + themeFromWebConfig + "/Index";
return View(viewName);