1. 程式人生 > >轉載:ASP.NET MVC擴展自定義視圖引擎支持多模板&動態換膚skins機制

轉載:ASP.NET MVC擴展自定義視圖引擎支持多模板&動態換膚skins機制

生效 amp 文件名 attr 情況 etc lis new out

ASP.NET mvc的razor視圖引擎是一個非常好的.NET MVC框架內置的視圖引擎。一般情況我們使用.NET MVC框架為我們提供的這個Razor視圖引擎就足夠了。但是有時我們想在我們的項目支持多模板&skins機制,比如我們可能會有多套的模板,也就是多個View風格,而我們只需要改一下配置文件就可以輕松的改變頁面的風格和模板。實現這個功能有兩種方式:

一、使用接口IViewEngine自己完成一個類似Razor視圖引擎的功能。

二、繼承類RazorViewEngine類,重寫它的一些方法達到自定義視圖引擎的目的。

顯然方法二是最簡單的,因此我們選最簡單方式實現這個功能。

1、首先,我們定義一個一些基礎的輔助類

標示支持Skin特性類:

技術分享
1 using System;
2 /// <summary>
3 /// 用於標示支持Skin換膚的特性
4 /// </summary>
5 public class SupportSkinAttribute : Attribute
6 {
7     
8 }
技術分享

風格配置結點讀取類:

技術分享
 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類:

技術分享
 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 }
技術分享

2、然後,定義CustomRazorViewEngine類

CustomRazorViewEngine.cs:

技術分享
 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的文件名。

如果風格名為lanhu,將按照以下的規則來創建視圖文件:

1、MasterLocationFormats(Layout)路徑為:~/skins/lanhu/views/lanhu.cshtml

2、ViewLocationFormats(視圖文件)路徑為:~/skins/lanhu/Views/{1}/{0}.cshtml,其中{1}和{0}分別表示Controller和Action的名字。

3、最後,註冊CustomRazorViewEngine

最後,在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文件夾的文件夾名),我們以後想換模板就是分分鐘的事。

轉載:ASP.NET MVC擴展自定義視圖引擎支持多模板&動態換膚skins機制