asp.net mvc theme主题皮肤的实现方法(一)

视图文件,默认是从~/view/{controller}/{action} 这个路径去寻找的(Areas类似)。现在,我需要实现主题模板 ,视图文件路径则被改成了 view/{theme}/{controller}/{action} . 
我们查看 源码,发现 默认RazorView 的文件查找是这样写的。 源文件:查看
            AreaViewLocationFormats = new[]
            {
                "~/Areas/{2}/Views/{1}/{0}.cshtml",
                "~/Areas/{2}/Views/{1}/{0}.vbhtml",
                "~/Areas/{2}/Views/Shared/{0}.cshtml",
                "~/Areas/{2}/Views/Shared/{0}.vbhtml"
            };
            AreaMasterLocationFormats = new[]
            {
                "~/Areas/{2}/Views/{1}/{0}.cshtml",
                "~/Areas/{2}/Views/{1}/{0}.vbhtml",
                "~/Areas/{2}/Views/Shared/{0}.cshtml",
                "~/Areas/{2}/Views/Shared/{0}.vbhtml"
            };
            AreaPartialViewLocationFormats = new[]
            {
                "~/Areas/{2}/Views/{1}/{0}.cshtml",
                "~/Areas/{2}/Views/{1}/{0}.vbhtml",
                "~/Areas/{2}/Views/Shared/{0}.cshtml",
                "~/Areas/{2}/Views/Shared/{0}.vbhtml"
            };

            ViewLocationFormats = new[]
            {
                "~/Views/{1}/{0}.cshtml",
                "~/Views/{1}/{0}.vbhtml",
                "~/Views/Shared/{0}.cshtml",
                "~/Views/Shared/{0}.vbhtml"
            };
            MasterLocationFormats = new[]
            {
                "~/Views/{1}/{0}.cshtml",
                "~/Views/{1}/{0}.vbhtml",
                "~/Views/Shared/{0}.cshtml",
                "~/Views/Shared/{0}.vbhtml"
            };
            PartialViewLocationFormats = new[]
            {
                "~/Views/{1}/{0}.cshtml",
                "~/Views/{1}/{0}.vbhtml",
                "~/Views/Shared/{0}.cshtml",
                "~/Views/Shared/{0}.vbhtml"
            };
其实很容易看出,格式化的时候,{0} 则对应 action ,{1} 则对应 controller ,{2} 则对应 area name 。因此,以 ViewLocationFormats 为例。则需要改成,
ViewLocationFormats = new[]
{
    "~/Views/{2}/{1}/{0}.cshtml",
    "~/Views/{2}/{1}/{0}.vbhtml",
    "~/Views/{2}/Shared/{0}.cshtml",
    "~/Views/{2}/Shared/{0}.vbhtml"
};
上面的 {2} 则是对应主题的名称,同时也是主题模板的文件夹名称。
因此,一种比较简单的实现方式是:
public class MyThemeViewEngine : RazorViewEngine
    {
        public MyThemeViewEngine()
        {
            string theme = "default";
            //TODO: get theme name here


            base.ViewLocationFormats = new string[]
			{
				"~/Views/"+theme+"{1}/{0}.cshtml",
				"~/Views/"+theme+"{1}/{0}.vbhtml",
				"~/Views/"+theme+"Shared/{0}.cshtml",
				"~/Views/"+theme+"Shared/{0}.vbhtml"
			};
            base.MasterLocationFormats = new string[]
			{
				"~/Views/"+theme+"{1}/{0}.cshtml",
				"~/Views/"+theme+"{1}/{0}.vbhtml",
				"~/Views/"+theme+"Shared/{0}.cshtml",
				"~/Views/"+theme+"Shared/{0}.vbhtml"
			};
            base.PartialViewLocationFormats = new string[]
			{
				"~/Views/"+theme+"{1}/{0}.cshtml",
				"~/Views/"+theme+"{1}/{0}.vbhtml",
				"~/Views/"+theme+"Shared/{0}.cshtml",
				"~/Views/"+theme+"Shared/{0}.vbhtml"
			}; 

            // Area Location Formats ....
        }
    }
在 Global.asax 中 :
        protected void Application_Start(object sender, EventArgs e)
        {
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new MyThemeViewEngine());
}
如果想将主题模板放在别的地方,原理也是一样。

已禁用评论。