传统的asp.net web forms是一个非常好的主意,但现实需求非常复杂。随着时间的推移,现实世界的项目暴露出web forms的一些不足之处:

“沉重的”视图状态:现实中在http请求之间维持状态(术语叫视图状态)导致了服务端和客户端巨大的数据块来回传递。典型情况下这个数据块会大到数百k字节,而且这个数据块会在每次请求时来回传输,导致网站访问者访问速度下降,同时增加了服务器的带宽负担。

页面生存周期:作为页面生存周期的一部分,连接客户端事件和服务端事件处理代码的机制,有时会非常复杂和微妙。很少有开发者能够在运行时成功操纵控件的层次结构而不发生视图状态错误,有时还会发现一些事件处理代码在运行神秘的失败了。

对html控制有限:服务端控件在客户端将自身转化为html标记,但往往并不是你想要的。在asp.net 4.0以前版本中,它的html输出通常并不符合web标准,和层叠样式表(css)也没有良好的结合,而且服务端控件自动创建不可预知的、复杂的标记id值,导致javascript难以访问。这些问题在在asp.net 4.0里有所改善,但要获取你期望的html标记可能依然比较棘手。

有问题的抽象:web forms试图尽可能隐藏html和http的实现细节。当你想要实现自定义的行为时,你必须频繁地从这种抽象里跳出来,强制你对回发事件机制实施进行逆向工程,采取一些繁琐的方法(obtuse acts)生成你想要的html文本。这些抽象甚至会令极富经验的web开发者感到令人沮丧的挫折。

低级的可测试性:asp.net的设计者压根没有把自动测试作为这个软件开发平台的必要工具。这并不奇怪,他们设计的紧密耦合的体系结构根本不合适进行单元测试,集成测试也是个问题。

asp.net在不断发展。2.0版增加了一套标准应用程序组件集,可以减少你需要自己输入的代码量。2007年发布的ajax版本是微软对当时web 2.0/ajax疯狂流行的响应,它支持富客户端交互。最近发布的asp.net 4.0版,可以产生大部分可以预见的符合标准的html标记,但许多其固有的局限性依然存在。

asp.net mvc的主要优势

asp.net在商业上取得了巨大成功,但正如前所述,其它的web开发平台也在不断向前发展。尽管微软一直在努力把緾绕在web forms上的“蜘蛛网”清除掉,但其内在的设计理念已经落伍了。

2007年10月份,在美国德克萨斯州奥斯丁市召开的第一届alt.net会议上,微软公司副总裁scott guthrie发布并演示了一个基于asp.net的崭新的mvc web开发平台,明确的被设计为针对类似rails这样的技术的直接响应,也是对业界关于web forms的批评的回应。本章的余下部分描述这个新的平台如何解决web forms的种种不足,并令asp.net重返顶峰。

(一) mvc体系结构

把mvc构建模式和asp.net mvc框架之间的区别搞清楚是十分重要的。mvc模式并不是新生事物-这要追溯到1978年施乐公司帕洛阿尔托研究中心的smalltalk项目-之所以在今天的web开发领域广受欢迎,有以下原因:

mvc应用程序的用户交互符合自然周期:用户执行一个动作,作为响应,应用程序改变它的数据模型,并向用户提供一个更新了的视图。应用程序就一直这样循环的运行。这种模式非常适合web应用程序传递

一连串的http请求和响应。

web应用程序必然要涉及若干不同的技术领域(数据库,html,可执行代码),通常这些技术都分布在不同层面。而mvc的概念很自然的就和这些技术的组合模式对应起来了。

asp.net mvc框架实现了mvc模式,而且这样做,有利于更好分离关注。实际上,asp.net mvc实现了一个特别为web应用开发定制的mvc模式。在第4章你将会了解这个体系的更多的理论,并亲身体验。

通过包含和改进mvc模式,asp.net mvc框架相对于ruby on rails这样的框架具备了强大的竞争力,同时也将mvc模式引入到主流的.net领域。通过使用其它平台的开发者提供的对asp.net mvc的体验评估和实际应用中反馈,asp.net mvc在许多方面甚至已经超越了rails。

(二) 可扩展性

你的桌面型电脑都是由一些相互独立的部分组成,它们之间通过标准的公开的文档化的接口相互联系。你可以很轻松的把你的显卡和硬盘换成另一个制造商生产的产品,并确信它们可以插进相应的槽位并正常工作。mvc框架的原理和pc一样也是构建在一系列相互独立的组件的基础之上-如一个可信的.net接口或继承抽象基类的用户类-这样你就可以轻而易举的用你自己的实现替换这些组件,诸如路由系统,视图引擎,控制器工厂等等。

asp.net mvc设计者对如何使用mvc框架的每个组件向你提供了三个选择:

使用默认组件实现(对于大部分应用来说已经足够了)

从默认实现继承实现一个子类,以对某些行为进行微调

使用新的接口或抽象基类实现替换这些组件

这些看起来有点像asp.net 2.0中的供给者模式(provider model),但它更进了一步-完全进入了mvc框架的核心。从第10章起,你将会了解到各种各样的组件,并且知道为什么要调整或替换它们。

(三) 对html代码和http的严密控制力(tight control over html and http)

asp.net mvc知道产生整洁、符合标准的标记的重要。它内置的html helper方法的输出完全符合标准,但同web forms相比较其更多的重要变化体现在其设计哲学上。以往你对web forms自动生成的一大堆令人作呕的封装的html标记只有很小的控制权,作为替代,mvc框架鼓励你使用css设计简洁、优雅的标记。

当然,如果你想在你的页面摆上一些现成的复合ui元素的小玩意,像日历或级联菜单,asp.net mvc中的“无特殊要求”的标记方法让你可以轻易的使用最好的ui库,比如jquery或雅虎的yui库。微软已经把jquery内置为asp.net mvc默认项目模板的一部分,javascript程序员会对asp.net mvc和当前流行的jquery库结合如此紧密感到欣慰,甚至在微软自己的内容分发网络(cdn)服务器上你都可以直接引用jquery.js文件。我们将在第20章涉及到jquery。

asp.net mvc生成的页面不包含任何视图状态数据,因此它们比典型的asp.net web forms页面会小数百k。尽管今天的宽带连接已经非常快了,但这种带宽的节约依然会给最终用户带来巨大的体验改善。

和ruby on rails一样,asp.net mvc和http合作和谐。你对往返于浏览器和服务器之间请求拥有完整的控制权,这样你就按你的喜好可以微调你的用户体验。ajax现在实现起来很简单,而且没有任何影响客户端状态的自动回发。关注web开发领域的任何开发者几乎肯定会发现,asp.net mvc会极大减少工作量,在同样的时间内完成的任务会更加令人满意。

(四) 易测试性

mvc使你在应用程序的可维护和可测试方面迈出了一大步,因为你可以自然的根据程序要实现的不同功能将其分离成许多不同的、相互独立的软件块。然而,asp.net mvc的设计师们并不满足于到底就止步了。为了支持单元测试,他们在框架中引入了面向组件设计的概念,并确保每个分离的代码块都以满足单元测试和模拟工具的需要的形式构建。

出于为开发者考虑的角度,他们还在visual studio向导中增加了创建单元测试向导,它可以使用许多开源的单元测试工具,如nunit和xunit,甚至微软自己的mstest。即使你以前从来没有写过单元测试代码,你也会有一个良好的开始。

本书中,你会看许多为asp.net mvc控制器(controller)和行为(action)编写的简洁、简单的单元测试示例,这些示例会使用各种测试和模拟策略来冒充框架组件的实现,以确定实际运行中可能出现的任何情况。

易测试性不只是体现在单元测试中,asp.net mvc应用程序和ui自动化测试工具之间工作也非常好。你可以模拟用户交互的情景编写测试脚本,再不用去猜测html元素的结构,使用的css类,或者框架将要生成的id,也用不着担心页面的结构会出现莫名其妙的变化。

(五) 强大的路由系统

url的风格伴随着web应用技术的发展也在不断发展。像下面的url:

/app_v2/user/page.aspx?action=show%20prop&prop_id=82742

将会逐渐稀少,它将被一种简单的、整洁的格式所代替,就像下面的这个:

/to-rent/chicago/2303-silver-street

之所以关注url的结构问题,有以下几个很好的原因:第一,搜索引擎给在url中搜索关键字分配了很大的权重。搜索“芝加哥的租金”会更容易匹配上面那个简单的url。第二,现在许多网络用户的理解能力足够搞明白一个url的意思,而且他们很欣赏在浏览器地址栏输入地址时的智能导航选项。第三,当人们理解了一个url的结构,他们更有可能去链接它,把它和朋友共享,甚至可以通过电话大声的读出来。第四,它不会把你的应用程序的技术细节,目录,文件名结构公开到整个互联网上,因此,你可以自由的改变底层的实现而不会影响到你已经拥有的连接。

早期的框架难以实现精准的url,不过asp.net mvc默认使用system.web.routing命名空间很容易提供精准的url。它可以让你控制你的url的样式,并将其和你的应用相关联,为你提供创造一个有意义的、对用户有用的地址样式的自由,不需要遵守预定义的模式。另外,只要你愿意,你完全可以容易的定义时髦的rest风格的url样式。你会第11章看到一个详细的路由方案和关于url的最佳练习。

(六) 构建于asp.net平台最好的部分之上

微软现有的asp.net平台已经为开发实用和高效的web应用程序提供了一整套成熟的、久经考验的组件和工具集。

首先也是最明显的地方,因为asp.net mvc构建在.net平台之上,所以用户可以灵活的使用任意.net语言编写代码和访问相同api功能-不光是mvc里面的,也包括大量的系统.net类库和浩瀚的第三方.net库。

其次,现有的asp.net平台的一些功能-比如母版页,表单验证,成员资格,角色,profiles,还有国际化-能够减少你需要开发和维护任意应用程序的代码量,这些功能在mvc框架中同样有效,因为它本来就是一个杰出的web forms项目。你可以在asp.net mvc的项目中继续使用一部分web forms内置的服务器控件,以及你在早期的asp.net项目中创建的自定义控件。(不过不能再依赖web forms中的特有概念,比如视图状态)

开发和布署是交替进行的。asp.net不仅和visual studio紧密结合在一起,它也作为一种原生的web编程技术为windows xp,vista,7和服务器操作系统中安装的internet信息服务(iis)所支持。iis7发布后,将.net托管代码它的请求处理管道的原生部分,为其提供第一流的支持,这也是asp.net的特殊待遇。因为mvc应用基于asp.net平台核心,因此它也会同样享受这些待遇。第23章我们会详细说明如何在windows服务器上的iis中部署mvc应用程序。

(六) 现代化的api

自微软2002年发布 .net平台以来,它一直在持续的发展,支持甚至是定义了现代编程技术顶级水准。

asp.net mvc是专为.net 4.0打造的,所以它的api可以使用最新的编程语言和运行时创新的所有益处,包含扩展方法,lambda表达式,匿名和动态类型,语言集成查询(linq)。许多mvc框架的api方法和编码模式尽可能的比早期平台整洁,更富表现力。

(七) asp.net mvc是开源的

和微软先前的平台不同,asp.net mvc的原始代码你可以随意下载,甚至可以对其进行修改,重新编译为你自己的版本。当你的调试足迹深入到一个系统组件内部,想对它的代码进行步进(甚至阅读原作者的注释)时,代码开源是非常有用的。另外,如果你想构建一个更高级的组件,看看可能会发生什么,或者观察内置组件是如何工作的,这点也非常有帮助。

同时,如果你不喜欢某些工作的实现方式,或者你发现了一个错误,又或者你想访问一些其它方式无法访问的东西,开源好处是非常强大的。因为你自己就可以简单的改变它。

不过,如果将来有一天你将你的框架升级到新版本,你还要重复你所作的改变再重新应用它们。asp.net mvc是按照微软公共许可(ms-pl,http://www.opensource.org/licenses/ms-pl.html)发布的,这是一个经过开源促进组织批准的开源许可。也就是说你能够修改源代码并部署它,甚至把它作为一个衍生项目向公众发布。然而,微软在其官方版本上不接受任何补丁,现阶段,微软只维护其产品开发和质量保证团队的负责的代码,你可以从http://aspnt.codeplex.com/网站上下载mvc的源代码。