ASP.NET MVC 实现多模版的方法
需要解决的场景:
不用的场景下使用不用的mvc 模版。
目录结构希望是
/templates
Default
Blue
Red
.....
当传入 “Blue” 参数的时候则调用 Blue 下面的View
查看 return View().. 的参数,发现可以指定 一个 IView 。
然后就有如下的代码。
RazorView rv = new RazorView(this.ControllerContext, "~/tempate/Blue/???.cshtml", null, true, new string[] { ".cshtml", ".vbcshtml" });
return View(rv);
然后,就解决了路径的问题。
执行,出错,不是正确的页面文件。
这个错误解决方法很简单(但也浪费了我不少时间):
把 /Views 下面的 web.config 拷贝到 /templates 下
更好一点的解决方法:
自己实现一个 IView。
1 using System;
2 using System.IO;
3 using System.Web.Compilation;
4 using System.Web.Mvc;
5 using System.Web.WebPages;
6
7 namespace System.Web.Mvc
8 {
9 public class ThemeRazorView : IView
10 {
11 private string template; //模版的目录名称
12
13 public ThemeRazorView(string _template)
14 {
15 this.template = _template;
16 }
17
18 public void Render(ViewContext viewContext, TextWriter writer)
19 {
20 //这个地方可以自己实现,或者从 web.config 里读取,或者从用户选择的模版中读取
21 if (template.IsNullOrEmpty())
22 {
23 template = "Default";
24 }
25 string viewPath = "~/templates/" + template + "/" + viewContext.RouteData.GetRequiredString("controller") + "/" + viewContext.RouteData.GetRequiredString("action") + ".cshtml";
26
27 Type viewType = BuildManager.GetCompiledType(viewPath);
28 var page = Activator.CreateInstance(viewType) as WebViewPage;
29
30 page.VirtualPath = viewPath;
31 page.ViewContext = viewContext;
32 page.ViewData = viewContext.ViewData;
33 page.InitHelpers();
34
35 WebPageContext pageContext = new WebPageContext(viewContext.HttpContext, null, null);
36 WebPageRenderingBase startPage = StartPage.GetStartPage(page, "_ViewStart", new string[] { "cshtml", "vbhtml" });
37
38 page.ExecutePageHierarchy(pageContext, writer, startPage);
39 }
40
41 }
42 }
3 using System.Web.Compilation;
4 using System.Web.Mvc;
5 using System.Web.WebPages;
6
7 namespace System.Web.Mvc
8 {
9 public class ThemeRazorView : IView
10 {
11 private string template; //模版的目录名称
12
13 public ThemeRazorView(string _template)
14 {
15 this.template = _template;
16 }
17
18 public void Render(ViewContext viewContext, TextWriter writer)
19 {
20 //这个地方可以自己实现,或者从 web.config 里读取,或者从用户选择的模版中读取
21 if (template.IsNullOrEmpty())
22 {
23 template = "Default";
24 }
25 string viewPath = "~/templates/" + template + "/" + viewContext.RouteData.GetRequiredString("controller") + "/" + viewContext.RouteData.GetRequiredString("action") + ".cshtml";
26
27 Type viewType = BuildManager.GetCompiledType(viewPath);
28 var page = Activator.CreateInstance(viewType) as WebViewPage;
29
30 page.VirtualPath = viewPath;
31 page.ViewContext = viewContext;
32 page.ViewData = viewContext.ViewData;
33 page.InitHelpers();
34
35 WebPageContext pageContext = new WebPageContext(viewContext.HttpContext, null, null);
36 WebPageRenderingBase startPage = StartPage.GetStartPage(page, "_ViewStart", new string[] { "cshtml", "vbhtml" });
37
38 page.ExecutePageHierarchy(pageContext, writer, startPage);
39 }
40
41 }
42 }
完成。
现在调用方法为:
return View(new ThemeRazorView("Blue"));
参考了:http://www.cnblogs.com/artech/archive/2012/04/10/how-mvc-works.html