zoukankan      html  css  js  c++  java
  • [转]ASP.NET MVC Dynamic Themes

    本文转自:http://www.codeproject.com/Articles/32847/ASP-NET-MVC-Dynamic-Themes

    Introduction

    I really needed to enable themes for my application, and I found an interesting article about it by Chris Pietschmann. In my point of view, the only problem with his approach is that you need to repeat each page for all themes. Well, I only want to create one page per theme, and have a master page and CSS files for each theme.

    Using the code

    For this project, I made some assumptions:

    • The master page for each theme has the name Site.Master.
    • The master page file and CSS files will be placed on a folder with the name of the theme.
    • All the theme folders will be placed in the Content folder.

    The file structure will be like this:

    Now, let’s write a custom View Engine that will inherit from WebFormViewEngine. This code is only a sketch of what I want to implement. For instance, I want to save the user theme selection so that, in the next login, the user has his option set.

    public class ThemeViewEngine : WebFormViewEngine
    {
        public ThemeViewEngine()
        {
            base.ViewLocationFormats = new string[] {
                "~/Views/{1}/{0}.aspx",
                "~/Views/{1}/{0}.ascx",
                "~/Views/Shared/{0}.aspx",
                "~/Views/Shared/{0}.ascx"
            };
    
            base.MasterLocationFormats = new string[] {
                "~/Content/{2}/Site.master"
            };
    
            base.PartialViewLocationFormats = new string[] {
                "~/Views/{1}/{0}.aspx",
                "~/Views/{1}/{0}.ascx",
                "~/Views/Shared/{0}.aspx",
                "~/Views/Shared/{0}.ascx"
            };
        }
    
        public override ViewEngineResult FindView(ControllerContext controllerContext, 
                        string viewName, string masterName)
        {
            if (controllerContext == null)
            {
                throw new ArgumentNullException("controllerContext");
            }
            if (string.IsNullOrEmpty(viewName))
            {
                throw new ArgumentException("Value is required.", "viewName");
            }
    
            string themeName = this.GetThemeToUse(controllerContext);
    
            string[] searchedViewLocations;
            string[] searchedMasterLocations;
    
            string controllerName = 
              controllerContext.RouteData.GetRequiredString("controller");
    
            string viewPath = this.GetViewPath(this.ViewLocationFormats, viewName, 
                              controllerName, out searchedViewLocations);
            string masterPath = this.GetMasterPath(this.MasterLocationFormats, viewName, 
                                controllerName, themeName, out searchedMasterLocations);
    
            if (!(string.IsNullOrEmpty(viewPath)) && 
               (!(masterPath == string.Empty) || string.IsNullOrEmpty(masterName)))
            {
                return new ViewEngineResult(
                    (this.CreateView(controllerContext, viewPath, masterPath)), this);
            }
            return new ViewEngineResult(
              searchedViewLocations.Union<string>(searchedMasterLocations));
        }
    
        public override ViewEngineResult FindPartialView(ControllerContext controllerContext, 
                                                         string partialViewName)
        {
            if (controllerContext == null)
            {
                throw new ArgumentNullException("controllerContext");
            }
            if (string.IsNullOrEmpty(partialViewName))
            {
                throw new ArgumentException("Value is required.", partialViewName);
            }
    
            string themeName = this.GetThemeToUse(controllerContext);
    
            string[] searchedLocations;
    
            string controllerName = controllerContext.RouteData.GetRequiredString("controller");
    
            string partialPath = this.GetViewPath(this.PartialViewLocationFormats, 
                                 partialViewName, controllerName, out searchedLocations);
    
            if (string.IsNullOrEmpty(partialPath))
            {
                return new ViewEngineResult(searchedLocations);
            }
            return new ViewEngineResult(this.CreatePartialView(controllerContext, 
                                        partialPath), this);
        }
    
        private string GetThemeToUse(ControllerContext controllerContext)
        {
            if (controllerContext.HttpContext.Request.QueryString.AllKeys.Contains("theme"))
            {
                string themeName = controllerContext.HttpContext.Request.QueryString["theme"];
                controllerContext.HttpContext.Session.Add("Theme", themeName);
            }
            else if (controllerContext.HttpContext.Session["Theme"] == null)
            {
                controllerContext.HttpContext.Session.Add("Theme", "Default");
            }
            return controllerContext.HttpContext.Session["Theme"].ToString();
        }
    
        private string GetViewPath(string[] locations, string viewName, 
                       string controllerName, out string[] searchedLocations)
        {
            string path = null;
    
            searchedLocations = new string[locations.Length];
    
            for (int i = 0; i < locations.Length; i++)
            {
                path = string.Format(CultureInfo.InvariantCulture, locations[i], 
                                     new object[] { viewName, controllerName });
                if (this.VirtualPathProvider.FileExists(path))
                {
                    searchedLocations = new string[0];
                    return path;
                }
                searchedLocations[i] = path;
            }
            return null;
        }
    
        private string GetMasterPath(string[] locations, string viewName, 
                       string controllerName, string themeName, out string[] searchedLocations)
        {
            string path = null;
    
            searchedLocations = new string[locations.Length];
    
            for (int i = 0; i < locations.Length; i++)
            {
                path = string.Format(CultureInfo.InvariantCulture, locations[i], 
                                     new object[] { viewName, controllerName, themeName });
                if (this.VirtualPathProvider.FileExists(path))
                {
                    searchedLocations = new string[0];
                    return path;
                }
                searchedLocations[i] = path;
            }
            return null;
        }
    }

    To finish this sample, just change the global.asax, removing all engines from the View Engine and adding the custom one:

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
    
        ViewEngines.Engines.Clear();
        ViewEngines.Engines.Add(new ThemeViewEngine());
    }

    Well, hope that’s useful.

    License

    This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  • 相关阅读:
    idea 本地tomcat启动控制台乱码问题
    继续mysql8navicat12连接登录的异常
    mysql8.0修改密码无效的问题
    markdown开源博客Gitblogv2.1版本发布更新
    Gitblog-v2.1.3版本发布更新
    Markdown博客系统Gitblog-V2.1版本代码更新
    使用Gitblog和Markdown搭建自己的博客网站
    MongoDB3.0集群配置文件自动生成器
    用redis实现社交产品中计数器
    InnoDB的doublewrite机制
  • 原文地址:https://www.cnblogs.com/freeliver54/p/5633820.html
Copyright © 2011-2022 走看看