ASP.NET MVC扩展自定义视图引擎支持多模板&动态换肤skins机制

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类

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的名字。

三、最后,注册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文件夹的文件夹名),咱们之后想换模板就是分分钟的事。

相关文章
相关标签/搜索