2012-07-26 14:17 5365人阅读 评论(0) 收藏 举报
 分类:
ASP.NET(12) 

版权声明:本文为博主原创文章,未经博主允许不得转载。

ASP.NET MVC出来这么久了,心中却又很多的疑惑:为什么所有的View都要放在Views目录下? 为什么Shared文件夹下面的页面可以被共享? 为什么Page既可以是*.cshtml,也可以是*.aspx?

其实上面的几个问题归结起来都是视图引擎的功效。

在传统的ASP.NET中,可能还没有ViewEngine的概念。因为在Web From里面,实现Page实现了IHttpHanlder的接口,所以Page既是响应的处理类,也是视图的渲染类。在ASP.NET MVC中,视图的概念被抽象了出来,试图引擎的概念也被抽象成了一个接口。

首先来看一下IViewEngine接口的定义:

  1. namespace System.Web.Mvc
  2. {
  3. public interface IViewEngine
  4. {
  5. ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache);
  6. ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache);
  7. void ReleaseView(ControllerContext controllerContext, IView view);
  8. }
  9. }
 

总共3个函数,总结起来大概就是两个功能:Find & Release。

默认情况下,ASP.NET MVC提供了两个视图引擎:WebFormViewEngine和RazorViewEngine。

  1. namespace System.Web.Mvc
  2. {
  3. public static class ViewEngines
  4. {
  5. private static readonly ViewEngineCollection _engines = new ViewEngineCollection
  6. {
  7. new WebFormViewEngine(),
  8. new RazorViewEngine(),
  9. };
  10. public static ViewEngineCollection Engines
  11. {
  12. get { return _engines; }
  13. }
  14. }
  15. }

这就是为什么ASP.NET MVC既支持*.aspx,又支持*.cshtml的原因了(个人觉得如果已经确定要使用RazorView的话,不如把WebFormViewEngine给移除,可能对性能会有所帮助)。

那为什么所有的视图都要放在Views目录下呢,这个就要拜RazorViewngines所赐了。

下面是RazorViewEngine的构造函数:

  1. public RazorViewEngine(IViewPageActivator viewPageActivator)
  2. : base(viewPageActivator)
  3. {
  4. AreaViewLocationFormats = new[]
  5. {
  6. "~/Areas/{2}/Views/{1}/{0}.cshtml",
  7. "~/Areas/{2}/Views/{1}/{0}.vbhtml",
  8. "~/Areas/{2}/Views/Shared/{0}.cshtml",
  9. "~/Areas/{2}/Views/Shared/{0}.vbhtml"
  10. };
  11. AreaMasterLocationFormats = new[]
  12. {
  13. "~/Areas/{2}/Views/{1}/{0}.cshtml",
  14. "~/Areas/{2}/Views/{1}/{0}.vbhtml",
  15. "~/Areas/{2}/Views/Shared/{0}.cshtml",
  16. "~/Areas/{2}/Views/Shared/{0}.vbhtml"
  17. };
  18. AreaPartialViewLocationFormats = new[]
  19. {
  20. "~/Areas/{2}/Views/{1}/{0}.cshtml",
  21. "~/Areas/{2}/Views/{1}/{0}.vbhtml",
  22. "~/Areas/{2}/Views/Shared/{0}.cshtml",
  23. "~/Areas/{2}/Views/Shared/{0}.vbhtml"
  24. };
  25. ViewLocationFormats = new[]
  26. {
  27. "~/Views/{1}/{0}.cshtml",
  28. "~/Views/{1}/{0}.vbhtml",
  29. "~/Views/Shared/{0}.cshtml",
  30. "~/Views/Shared/{0}.vbhtml"
  31. };
  32. MasterLocationFormats = new[]
  33. {
  34. "~/Views/{1}/{0}.cshtml",
  35. "~/Views/{1}/{0}.vbhtml",
  36. "~/Views/Shared/{0}.cshtml",
  37. "~/Views/Shared/{0}.vbhtml"
  38. };
  39. PartialViewLocationFormats = new[]
  40. {
  41. "~/Views/{1}/{0}.cshtml",
  42. "~/Views/{1}/{0}.vbhtml",
  43. "~/Views/Shared/{0}.cshtml",
  44. "~/Views/Shared/{0}.vbhtml"
  45. };
  46. FileExtensions = new[]
  47. {
  48. "cshtml",
  49. "vbhtml",
  50. };
  51. }

所有的寻址路径都被格式化了,是不是很眼熟呢,关于这里为啥用数组而不用List,个人觉得,数组的寻址效率要更高些,遍历速度更快。

好了,找了“罪魁祸首”,就好好地调教一个,让它乖乖听话,小样让去哪就去哪里。

  1. namespace MvcApplicatin.Web.Mvc.ViewEngine
  2. {
  3. public sealed class CustomViewEngine : RazorViewEngine
  4. {
  5. public CustomViewEngine()
  6. {
  7. ViewLocationFormats = new[]
  8. {
  9. "~/Views/{1}/{0}.cshtml",
  10. "~/Views/Shared/{0}.cshtml",
  11. "~/CustomViewLocation/{1}/{0}.cshtml"
  12. };
  13. }
  14. public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
  15. {
  16. return base.FindView(controllerContext, viewName, masterName, useCache);
  17. }
  18. }
  19. }

我使用开发语言是C#,视图是Razor,所以稍稍修改了下ViewLocationFormats,让寻址路径能够寻到CustomViewLocation下面的视图。

接下去就很简单了,只需要把原来的视图引擎清空,加载自己的视图引擎就可以了。

  1. protected void Application_Start()
  2. {
  3. AreaRegistration.RegisterAllAreas();
  4. ViewEngines.Engines.Clear();
  5. ViewEngines.Engines.Add(new CustomViewEngine());
  6. RegisterGlobalFilters(GlobalFilters.Filters);
  7. RegisterRoutes(RouteTable.Routes);
  8. }

最新文章

  1. Unity3D "Library\UnityAssemblies\UnityEngine.xml" is denied错误解决方法
  2. 一个苹果证书如何多次使用——导出p12文件
  3. python脚本执行Scapy出现IPv6警告WARNING解决办法
  4. GEF: 图形拖拽处理
  5. Dynamics CRM4.0 和 Dynamics CRM2011 Plugin 实现一样的功能的方法的比较
  6. C++ 第一次上机作业
  7. 317. Shortest Distance from All Buildings
  8. 面向对象的异常处理之深入理解java异常处理机制
  9. docker文章
  10. [置顶] .NET下枚举类型的Save和Load分析
  11. 深入理解 JavaScript 事件循环(一)— event loop
  12. codeforces-1140 (div2)
  13. c语言01次作业--分支,顺序结构
  14. s6-5 TCP 连接的建立
  15. 点击事件target
  16. 完全二叉树的节点个数 Count Complete Tree Nodes
  17. 常用的第三方模块 requests url
  18. C#aspx页面前台使用<%=%>无法取到后台的值
  19. Python面试题整理-更新中
  20. css中的相对定位与绝对定位的区别

热门文章

  1. iOS——学习网址收集+如何提高iOS开发技能
  2. RapidJSON 代码剖析(二):使用 SSE4.2 优化字符串扫描
  3. 当泛型方法推断,扩展方法遇到泛型类型in/out时。。。
  4. myeclipse 2014 除了 默认加载的derby
  5. JavaScript----Js操控-HTML5 <progress> 标签
  6. linux终端常用快捷键
  7. Redis 学习(二)
  8. '0000-00-00 00:00:00' can not be represented as java.sql.Timestamp error
  9. 【Beta】Scrum05
  10. <<< tomcat启动报错StandardServer.await: create[8005]