标签:
制作blog系统或者通用cms系统的时候,我们经常会用到Theme功能。asp.net mvc中的一种实现方式,是继承实现RazorViewEngine即可。
这是在GitHub中找到的一个示例:https://github.com/benedict-chan/ThemedViewEngines
结构如下图:
实现的核心代码ThemedRazorViewEngine.cs:
1 using System; 2 using System.Web.Mvc; 3 4 namespace ThemedViewEngines 5 { 6 public class ThemedRazorViewEngine : RazorViewEngine 7 { 8 private readonly IThemeSelectorService _themeSelectorService; 9 public string DefaultMasterName { get; set; } 10 public ThemedRazorViewEngine(IThemeSelectorService themeSelectorService) 11 : base() 12 { 13 DefaultMasterName = "_Layout"; 14 this._themeSelectorService = themeSelectorService; 15 16 AreaViewLocationFormats = new[] 17 { 18 "~/#@/Areas/{2}/Views/{1}/{0}.cshtml", 19 "~/#@/Areas/{2}/Views/{1}/{0}.vbhtml", 20 "~/#@/Areas/{2}/Views/Shared/{0}.cshtml", 21 "~/#@/Areas/{2}/Views/Shared/{0}.vbhtml", 22 23 "~/Areas/{2}/Views/{1}/{0}.cshtml", 24 "~/Areas/{2}/Views/{1}/{0}.vbhtml", 25 "~/Areas/{2}/Views/Shared/{0}.cshtml", 26 "~/Areas/{2}/Views/Shared/{0}.vbhtml" 27 }; 28 AreaMasterLocationFormats = new[] 29 { 30 "~/#@/Areas/{2}/Views/{1}/{0}.cshtml", 31 "~/#@/Areas/{2}/Views/{1}/{0}.vbhtml", 32 "~/#@/Areas/{2}/Views/Shared/{0}.cshtml", 33 "~/#@/Areas/{2}/Views/Shared/{0}.vbhtml", 34 35 "~/Areas/{2}/Views/{1}/{0}.cshtml", 36 "~/Areas/{2}/Views/{1}/{0}.vbhtml", 37 "~/Areas/{2}/Views/Shared/{0}.cshtml", 38 "~/Areas/{2}/Views/Shared/{0}.vbhtml" 39 }; 40 AreaPartialViewLocationFormats = new[] 41 { 42 "~/#@/Areas/{2}/Views/{1}/{0}.cshtml", 43 "~/#@/Areas/{2}/Views/{1}/{0}.vbhtml", 44 "~/#@/Areas/{2}/Views/Shared/{0}.cshtml", 45 "~/#@/Areas/{2}/Views/Shared/{0}.vbhtml", 46 47 "~/Areas/{2}/Views/{1}/{0}.cshtml", 48 "~/Areas/{2}/Views/{1}/{0}.vbhtml", 49 "~/Areas/{2}/Views/Shared/{0}.cshtml", 50 "~/Areas/{2}/Views/Shared/{0}.vbhtml" 51 }; 52 53 ViewLocationFormats = new[] 54 { 55 "~/#@/Views/{1}/{0}.cshtml", 56 "~/#@/Views/{1}/{0}.vbhtml", 57 "~/#@/Views/Shared/{0}.cshtml", 58 "~/#@/Views/Shared/{0}.vbhtml", 59 60 "~/Views/{1}/{0}.cshtml", 61 "~/Views/{1}/{0}.vbhtml", 62 "~/Views/Shared/{0}.cshtml", 63 "~/Views/Shared/{0}.vbhtml" 64 }; 65 MasterLocationFormats = new[] 66 { 67 "~/#@/Views/{1}/{0}.cshtml", 68 "~/#@/Views/{1}/{0}.vbhtml", 69 "~/#@/Views/Shared/{0}.cshtml", 70 "~/#@/Views/Shared/{0}.vbhtml", 71 72 "~/Views/{1}/{0}.cshtml", 73 "~/Views/{1}/{0}.vbhtml", 74 "~/Views/Shared/{0}.cshtml", 75 "~/Views/Shared/{0}.vbhtml" 76 }; 77 PartialViewLocationFormats = new[] 78 { 79 "~/#@/Views/{1}/{0}.cshtml", 80 "~/#@/Views/{1}/{0}.vbhtml", 81 "~/#@/Views/Shared/{0}.cshtml", 82 "~/#@/Views/Shared/{0}.vbhtml", 83 84 "~/Views/{1}/{0}.cshtml", 85 "~/Views/{1}/{0}.vbhtml", 86 "~/Views/Shared/{0}.cshtml", 87 "~/Views/Shared/{0}.vbhtml" 88 }; 89 FileExtensions = new[] 90 { 91 "cshtml", 92 "vbhtml", 93 }; 94 } 95 protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) 96 { 97 string replacedPartialPath = GetThemedPath(partialPath); 98 return base.CreatePartialView(controllerContext, replacedPartialPath); 99 } 100 protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) 101 { 102 string replacedViewPath = GetThemedPath(viewPath); 103 string replacedMasterPath = GetThemedPath(masterPath); 104 return base.CreateView(controllerContext, replacedViewPath, replacedMasterPath); 105 } 106 protected override bool FileExists(ControllerContext controllerContext, string virtualPath) 107 { 108 string replacedVirtualPath = GetThemedPath(virtualPath); 109 return base.FileExists(controllerContext, replacedVirtualPath); 110 } 111 public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) 112 { 113 var themeName = this._themeSelectorService.GetThemeName(); 114 if (!string.IsNullOrEmpty(themeName) && string.IsNullOrEmpty(masterName)) 115 { 116 //In case if we have a theme, and the request view is not found in the theme folder (i.e. we will use the default view), 117 // we will not be able to locate the theme‘s master page via _ViewStart (as the view is now in the default "theme" tree ) 118 //Therefore we have to manually locate the Master page name here 119 masterName = DefaultMasterName; 120 } 121 return base.FindView(controllerContext, viewName, masterName, false); 122 } 123 private string GetThemedPath(string originalPath) 124 { 125 var replacedPath = originalPath; 126 var themeName = this._themeSelectorService.GetThemeName(); 127 if (!string.IsNullOrEmpty(themeName)) 128 { 129 string replaceText = string.Format("Themes/{0}", themeName); 130 replacedPath = originalPath.Replace("#@", replaceText); 131 } 132 return replacedPath; 133 } 134 } 135 }
ConfigThemeService.cs的代码
1 namespace ThemedViewEngines 2 { 3 public class ConfigThemeService : IThemeSelectorService 4 { 5 public string GetThemeName() 6 { 7 return ConfigurationManager.AppSettings["ThemeName"] ?? string.Empty; 8 } 9 public void SetThemeName(string themeName) 10 { 11 throw new NotSupportedException(); 12 } 13 14 } 15 }
IThemeSelectorService.cs的代码:
1 namespace ThemedViewEngines 2 { 3 public interface IThemeSelectorService 4 { 5 /// <summary> 6 /// 获取Theme名称 7 /// </summary> 8 /// <returns></returns> 9 string GetThemeName(); 10 /// <summary> 11 /// 设置主题名称 12 /// </summary> 13 /// <param name="themeName"></param> 14 void SetThemeName(string themeName); 15 } 16 }
CookieThemeService.cs的代码
1 using System; 2 using System.Web; 3 4 namespace ThemedViewEngines 5 { 6 public class CookieThemeService : IThemeSelectorService 7 { 8 public string GetThemeName() 9 { 10 var cookie = HttpContext.Current.Request.Cookies["ThemeName"]; 11 if (cookie != null) 12 return cookie.Value; 13 return string.Empty; 14 } 15 16 public void SetThemeName(string themeName) 17 { 18 throw new System.NotImplementedException(); 19 } 20 } 21 }
调用方式:
1、新建mvc项目
2、根据上图中的示例建立Themes文件夹,Themes下面新建blue和red文件夹,然后分别把Views下的文件复制到blue和red中(主要是web.config一定要复制过去,不然没有智能提示)
3、添加引用ThemedViewEngines类库
4、在global文件的Application_Start方法下添加:
1 ViewEngines.Engines.Clear(); 2 //用 Web.config 配置 theme 的写法 3 ViewEngines.Engines.Add(new ThemedRazorViewEngine(new ConfigThemeService())); 4 //用cookie配置theme的写法 5 //ViewEngines.Engines.Add(new ThemedRazorViewEngine(new CookieThemeService()));
5、在Web.config的appSettings节点下添加:
<!--Theme配置--> <add key="ThemeName" value="blue" /> <!--Theme配置 end-->
6、运行项目即可。
Demo下载
asp.net mvc中换肤机制类库 ThemedViewEngines
标签:
原文地址:http://www.cnblogs.com/wxb8/p/5725028.html