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 ....
    }
}</pre><div>在&nbsp;Global.asax 中 :</div><pre>        protected void Application_Start(object sender, EventArgs e)
    {
        <span style="color: rgb(255, 0, 0);">ViewEngines.Engines.Clear();
        ViewEngines.Engines.Add(new <span style="line-height: 1.42857143;">MyThemeViewEngine</span><span style="line-height: 1.42857143;">());</span></span><br>        }</pre><div>如果想将主题模板放在别的地方,原理也是一样。</div>