ASP.NET mvc的razor視圖引擎是一個很是好的.NET MVC框架內置的視圖引擎。通常狀況咱們使用.NET MVC框架爲咱們提供的這個Razor視圖引擎就足夠了。可是有時咱們想在咱們的項目支持多模板&skins機制,好比咱們可能會有多套的模板,也就是多個View風格,而咱們只須要改一下配置文件就能夠輕鬆的改變頁面的風格和模板。實現這個功能有兩種方式:html
1、使用接口IViewEngine本身完成一個相似Razor視圖引擎的功能。mvc
2、繼承類RazorViewEngine類,重寫它的一些方法達到自定義視圖引擎的目的。框架
顯然方法二是最簡單的,所以咱們選最簡單方式實現這個功能。ide
標示支持Skin特性類:函數
1 using System; 2 /// <summary> 3 /// 用於標示支持Skin換膚的特性 4 /// </summary> 5 public class SupportSkinAttribute : Attribute 6 { 7 8 }
風格配置結點讀取類:spa
1 using System; 2 using System.Configuration; 3 using System.Web; 4 5 public class Utils 6 { 7 private static string _skinName; 8 9 public static string SkinName 10 { 11 get 12 { 13 if (!string.IsNullOrEmpty(_skinName)) 14 { 15 return _skinName; 16 } 17 //模板風格 18 _skinName = ConfigurationManager.AppSettings["Skin"]; 19 return _skinName; 20 } 21 } 22 }
Helper類:code
1 public class CustomViewEngineHelper 2 { 3 internal static string[] AddNewLocationFormats(IEnumerable<string> defaultLocationFormats,IEnumerable<string> newLocationFormats) 4 { 5 List<string> allItems = new List<string>(newLocationFormats); 6 foreach (string s in defaultLocationFormats) 7 { 8 allItems.Add(s); 9 } 10 11 return allItems.ToArray(); 12 } 13 14 15 internal static string OverrideMasterPage(string masterName, ControllerContext controllerContext) 16 { 17 if (NeedChangeMasterPage(controllerContext)) 18 { 19 masterName = Utils.SkinName; 20 } 21 22 return masterName; 23 } 24 25 private static bool NeedChangeMasterPage(ControllerContext context) 26 { 27 SupportSkinAttribute attr = Attribute.GetCustomAttribute(context.Controller.GetType(), typeof (SupportSkinAttribute)) as SupportSkinAttribute; 28 return null != attr; 29 } 30 }
CustomRazorViewEngine.cs:orm
1 public class CustomRazorViewEngine : RazorViewEngine 2 { 3 public CustomRazorViewEngine() 4 { 5 string[] mastersLocation = new[]{string.Format("~/skins/{0}/views/{0}.cshtml", Utils.SkinName)}; 6 MasterLocationFormats = CustomViewEngineHelper.AddNewLocationFormats( 7 new List<string>(MasterLocationFormats), 8 mastersLocation); 9 10 string[] viewsLocation = new[]{ string.Format("~/skins/{0}/Views/{{1}}/{{0}}.cshtml",Utils.SkinName)}; 11 //視圖文件位置路徑的格式 12 ViewLocationFormats = 13 PartialViewLocationFormats = 14 CustomViewEngineHelper.AddNewLocationFormats(new List<string>(ViewLocationFormats), viewsLocation); 15 } 16 17 //查找視圖文件 18 public override ViewEngineResult FindView(ControllerContext controllerContext,string viewName,string masterName,bool useCache) 19 { 20 masterName = CustomViewEngineHelper.OverrideMasterPage(masterName,controllerContext); 21 return base.FindView(controllerContext,viewName, masterName,useCache); 22 } 23 }
上面代碼是最核心的部分,咱們在CustomRazorViewEngine類構造函數中就按照咱們自定約定規則重寫了MasterLocationFormats(~/skins/{0}/views/{0}.cshtml)和ViewLocationFormats(~/skins/{0}/Views/{{1}}/{{0}}.cshtml)屬性,最後在FindView方法中重寫了master的文件名。htm
若是風格名爲lanhu,將按照如下的規則來建立視圖文件:blog
一、MasterLocationFormats(Layout)路徑爲:~/skins/lanhu/views/lanhu.cshtml
二、ViewLocationFormats(視圖文件)路徑爲:~/skins/lanhu/Views/{1}/{0}.cshtml,其中{1}和{0}分別表示Controller和Action的名字。
最後,在Appication_Start中加入下面的代碼,使用CustomRazorViewEngine生效
1 ViewEngines.Engines.Clear(); 2 ViewEngines.Engines.Add(new CustomRazorViewEngine());
上面第一行是清除默認的視圖引擎,接下來把咱們自定義的CustomRazorViewEngine註冊到MVC框架中使用其生效。
使用CustomRazorViewEngine提供的多模板&skins換膚機制,要在Controller類前面加上特性SupportSkin,以下代碼:
1 [SupportSkin] 2 public class HomeController 3 { 4 //省略其它代碼 5 }
這樣ASP.NET MVC視圖引擎就支持多模板&skins換膚機制了,咱們只須要增長一個風格,在skins文件夾中建立本身的風格的文件夾,並添加相應的視圖。最後,在把Web.config的配置結點名爲Skin的值改爲,相應的風格名稱(即skins文件夾的文件夾名),咱們之後想換模板就是分分鐘的事。