I am creating an ASP.Net Core 2.1 MVC application, and I recently came across making interchangeable themes for an ASP.Net MVC 6 application by using the web.config file to configure which custom view engine would be used to serve up views that are in different locations (depending on the view engine selected). By inserting the custom view engine (which was just an extension of the razor view engine with different path locations for the view) before the razor view engine, the developer only had to create new views for the ones he wanted to replace in the new theme and the default view engine would still return any of the views that didn't need to be changed. I was wondering if there would be a way to change the view engine or just the first view engine to be used to find the view during runtime by having the user select it from a drop down while the app is running. We need the URLs to remain the same between the two themes, and I would like to not include query strings to be able to pick a theme. To clarify, a theme here is more than just changing the color scheme. The layout of the page and the contents of the page will change also. I tried serving up a singleton of IServiceCollection to the controllers, to change the view location format, but sadly this is only when the app first starts up. I'm sure this seems like a weird request, but we want to be able to have the testers change the themes of the views on their end through the UI rather than having to keep making changes in the startup or config files. I've linked to where I first came across this idea of Themes; however, it requires a Pluralsight license. I've included the relevant code snippets as an example.

https://app.pluralsight.com/player?course=mvc-applications-10-extension-points-improving&author=alex-wolf&name=mvc-applications-10-extension-points-improving-m5&clip=2&mode=live

protected void Application_Start()
{
    if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["ActiveTheme"]))
    {
        var activeTheme = ConfigurationManager.AppSettings["ActiveTheme"];
        ViewEngines.Engines.Insert(0, new ThemeViewEngine(activeTheme));
    };

    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}
public class ThemeViewEngine : RazorViewEngine
{
    public ThemeViewEngine(string activeThemeName)
    {
         ViewLocationFormats = new[]
         {
             "~/Views/Themes/" + activeThemeName + "/{1}/{0}.cshtml",
             "~/Views/Themes/" + activeThemeName + "/Shared/{0}.cshtml"
         };

         PartialViewLocationFormats = new[]
         {
             "~/Views/Themes/" + activeThemeName + "/{1}/{0}.cshtml",
             "~/Views/Themes/" + activeThemeName + "/Shared/{0}.cshtml"
         };

         AreaViewLocationFormats = new[]
         {
             "~Areas/{2}/Views/Themes/" + activeThemeName + "/{1}/{0}.cshtml",
             "~Areas/{2}/Views/Themes/" + activeThemeName + "/Shared/{0}.cshtml"
         };

         AreaPartialViewLocationFormats = new[]
         {
             "~Areas/{2}/Views/Themes/" + activeThemeName + "/{1}/{0}.cshtml",
             "~Areas/{2}/Views/Themes/" + activeThemeName + "/Shared/{0}.cshtml"
         };
     }
}

0 Answers