为什么要坚持用ASP.NET MVC!(一)

ASP.NET MVC是微软的一个web开发框架,它整合了“模型-视图-控制器(MVC)”体系结构的效率与简洁、敏捷开发最现代的思想与技术、以及当前ASP.NET平台最好的部分。它是传统的ASP.NET Web表单的一种完善的替代品,即使是对最微不足道的web项目,它都具备了相当的优势。

    ASP.NET在它2002年刚问世时是一个巨大的转变。图1-1描述了它出现时微软的技术堆栈。

图3-1 图3-1c
    利用Web表单,微软试图通过把用户界面(UI)模拟为服务器端控件对象层的办法,把HTTP(具有无状态本质)和HTML(当时许多开发人员尚不熟悉)都隐藏起来。每个控件都跨请求地跟踪自己的状态(利用视图状态功能)、在需要时把自己渲染成HTML、并自动地把客户端事件(如按钮点击)与相应的服务器端的事件处理代码相关联。结果,Web表单变成了一个巨大的抽象层,它被设计在Web上递送传统的事件驱动GUI式(图形用户界面)了。其思想是,让web开发在感觉上与Windows窗口开发相同。开发者不再必须以一系列独立的HTTP请求和响应进行工作 — 现在可以把它说成是有状态的UI。我们可以忘记Web及其无状态本质,转而用一个拖-放设计器来建立各种UI,并假想,或至少假装,所有事情都发生在服务器上。
   ASP.NET WebForm为开发者设计了一个在可视化设计器中拖放控件,编写代码响应事件的快速开发环境。把过去桌面开发习惯沿用到Web开发之中。但是在应用过程中发现有诸多的问题!
1.ViewState问题
    视图状态负荷:跨请求状态维护的实际机制(称为视图状态)导致在客户端与服务器之间传递大块数据。这种数据即  使在最适度的web应用程序中也达到几百KB,而且它来回于每次请求之间,以很慢的响应时间阻挠着网站的访问者,且增加了服务器带宽的需求。在开发过程中容易得到一个包含大量ViewState的页面,使得页面尺寸远远超过所需的内容,使得页面的打开速度较慢,尤其是大型网站!
2.页面生命周期
    连接客户端事件与服务器端事件处理代码的机制(是页面的部分生命周期)格外复杂和棘手。很少有开发者能够成功地维护控件层而不产生视图状态错误,或不发现某些事件处理程序莫明其妙地不能执行。
3.关注分离的错误理解
    ASP.NET的后台代码模型提供了一种手段,把应用程序代码从它的HTML标记中提取出来,并放到一个独立的后台代码类中。这种逻辑与表现的分离得到了广泛的赞许,但在实际应用中,却又鼓励开发者在这些怪异的后台代码类中把表现代码(如维护服务器端控件树)与它们的应用程序逻辑(如维护数据库数据)混在一起。最终结果是脆弱和难以理解。
4.HTML上的受限控制
    服务器控件把自己渲染成HTML,但并不是你所希望的必要的HTML。在ASP.NET 4之前,这种HTML输出通常不符合web标准,或不能很好地使用CSS,而且,服务器控件生成不可预知且复杂的ID值,结果,这些ID难以用JavaScript进行访问。这些问题在ASP.NET 4中减少了,但仍然不容易得到你所期望的HTML。又由于大量控件封装了很多东西,开发者很难了解这背后的HTML是如何运作的。
5.低可测试性
    ASP.NET的设计者们未能预期到自动测试会成为软件开发的主要成分。毫不奇怪,他们设计的这种紧耦合体系结构不适合单元测试。集成测试也很具挑战性。
6.UI层无法真正分离
    ASP.NET WebForm大量使用各种紧耦合的控件与模板,并极大程度整合了MVC模式中的V和C的关系,虽然独具特色,却增强了应用程序的UI层耦合性。
    就在我们一直对Web技术的好坏纠结不下,WebForm与MVC之争正如火如荼之时,关于Web标准与REST的各种争论也开始了。向web标准靠拢近年来已经增强。Web网站建立在比以往更广泛的设备和浏览器之上,web标(HTML、CSS、JavaScript等等)使我们有望能够在任何地方 — 甚至在可联网的冰箱上 — 都可以有相当好的浏览体验。现代web平台不可忽视商业环境和开发者对顺应web标准的挚爱。与此同时,表现式状态传输(REST)已经成为应用程序在HTTP上互操作的主要体系结构,完全使SOAP(ASP.NET原先进行web服务的支撑技术)黯然失色。REST根据表示真实世界实体的资源(URI)和表示在这些资源上可用的标准操作(HTTP方法)来描述一个应用程序。当今的web应用程序不只服务于HTML,通常它们也必须把JSON或XML数据提供给各种客户端技术,包括AJAX、Silverlight,以及本地智能手机应用程序。利用REST,这会很自然地发生。REST消除了历史上web服务与web应用程序之间的差异 — 但这需要一种对HTTP和URL进行处理的办法,而这种办法对ASP.NET Web表单而言却难以得到支持。
    2004年Ruby on Rails还默默无闻,只是一个无名倡导者的开源项目。突然声名鹤唳,转变着web开发的规则。并不是它包含了革命性的技术,而是它利用了已有的成分,并把它们掺和成一种引人注目的方式,而使现有的平台感到羞愧。Ruby on Rails(或通常所说的Rails)采纳了一种模型-视图-控制器体系结构。通过运用MVC并配合而不是违背HTTP协议进行工作、用发扬约定代替需要配置、以及把对象关系映射(ORM)工具集成到它的内核等,Rails应用程序或多或少都能循序渐进而无需太多努力。就好像web开发一直就应该是这样,好像我们突然地意识到,所有这些年我们都是在进行工具战争,而现在,战争结束了。Rails表明,顺应web标准和REST化并不困难。它也表明,当框架支持敏捷开发与TDD时,它们工作是最好的。从那时起,整个web开发世界都被调动起来了。
    而这方面走的更远的是Sinatra。Sinatra摒弃了几乎所有标准的Rails风格的基础结构(路由、控制器、视图等),而仅把URL模式映射到Ruby代码块。一个访问者请求一个URL,这会引起执行一个Ruby代码块,并把数据送回浏览器 这就行了。这是一个难以置信的简单的web开发形式,但它只在两个主要方面奠定了一个小环境。第一,对那些建立REST化的web服务,它恰好能快速完成工作(我们在第14章简单涉及REST)。第二,由于Sinatra可以连接广泛的开源HTML模板和ORM技术,通常以此为基础来装配一个自定义的web框架,以适应手头各种项目的体系结构需求。Sinatra还需要从大堆的MVC平台如Rails(或ASP.NET MVC)中占据大片的市场份额。我们在这里简单地提到它,只是想勾画web开发行业正在朝着简化的方向发展,也因为Sinatra起到对抗其它框架(甚至聚集了更核心的特性)的作用。
MVC的体系结构
    重要的是区别MVC体系结构模式与MVC框架。MVC模式并不新 — 这要回溯到1978年Xerox PARC的Smailltalk项目 — 但它作为一种web应用程序的体系结构,如今已得到了巨大的普及,原因如下:
1.用户与MVC应用程序的交互遵循一种自然周期:用户采取一个动作,应用程序对之做出响应,以修改其数据模型,并把一个更新的视图提供给该用户。然后重复这一周期。这非常适合于以一系列HTTP请求与响应进行传递的web应用程序。
2.Web应用程序必须组合多种技术(如数据库、HTML、可执行代码等等),这通常分成一组层次。这些组合所产生的设计模式自然地映射到了MVC的概念上。
    ASP.NET MVC框架实现了这种MVC模式 — 而且极大地改善了关注分离。事实上,ASP.NET MVC实现了MVC的现代化的变异,它特别适用于web开发的MVC。通过采纳和调整MVC模式,ASP.NET MVC框架形成了对Roby on Rails以及类似平台强有力的竞争,并把MVC模式带到了.NET世界的主流。利用开发人员使用其它平台的体验和最优方法,ASP.NET MVC在许多方面的推进甚至已经超越了Rails,尤其配合LINQ TO Entities的使用!
ASP.NET MVC 可圈可点之处:
可扩展性
   桌面电脑的内部组件是一个个独立的部件,它们只通过标准的公共文档接口进行交互。你可以很容易地拔出显卡或硬盘,并用另一制造商的来替换,相信它会在插槽中正常工作。MVC框架也被构建成一系列独立的组件 — 满足一个.NET接口,或建立在一个抽象类之上 — 因此,你可以很容易地用一个自己的不同实现来替换相应组件,如,替换路由系统、视图引擎、控制器工厂等等。ASP.NET MVC设计者对每一个MVC框架组件都为你提供了三种选择:
      # 使用组件现行的默认实现(它应该足以满足大多数应用程序)。
      # 派生默认实现的一个子类,以调整其行为。
      # 用接口或抽象基类的一个新实现来完全替换该组件。
在HTML及HTTP上的密切控制
   ASP.NET MVC认识到产生干净的、标准兼容的标记的重要性。其内建的HTML辅助器方法产生标准兼容的输出 — 但与Web表单相比,有更重要的完善变革。替代原先那种喷出大片你无法控制的HTML标记,MVC框架鼓励你构思简单、雅致的可设置CSS样式的标记。当然,如果你确实想对复杂UI元素使用一些现成的部件,如,日期选择器或级联菜单等,ASP.NET MVC的“无特殊需求”标记方法可以很容易地使用最佳品种UI库,如jQuery库或Yahoo UI库等。JavaScript开发者如果了解到,微软已经把jQuery装配为默认ASP.NET MVC项目模板的一个内建部件,ASP.NET MVC与通用jQuery库啮合得如此良好,而且,甚至让你能够直接引用微软自己的内容分发网络(CDN)服务器上的jQuery的.js文件,他们会感到非常开心。ASP.NET MVC生成的页面不含任何视图状态数据,因此,这些网页可能比典型的ASP.NET Web表单页面要小几百KB。(哦,典型的Webform的ViewState问题!)无论今天的快速带宽如何,这种经济带宽仍然极大地改善了终端用户的体验。与Ruby on Rails一样,ASP.NET MVC与HTTP工作十分协调。你对传递于浏览器与服务器之间的请求有完全的控制,因此只要愿意,你可以仔细地调节用户体验。Ajax很容易使用,而且没有任何自动回递扰乱客户端状态 — 任何主要关注于Web的开发人员几乎肯定会发现这是极大的解放,且让人工作愉快。
强大的路由系统
  随着web应用程序技术的改进,URL样式已经产生了演变 — 像这样的URL:
    /App_v2/User/Page.aspx?action=show%20prop&prop_id=82742    明显罕见了,代之以一种更简单、更清晰的格式,像这样:
    /to-rent/chicago/2303-silver-street
   考虑这种URL结构有一些很好的理由。首先,搜索引擎对一个URL中找到的关键词有明显的权重。一个对“九寨沟租房”的搜索,更可能找到的是一个较简单的URL。其次,许多web用户现在对一个URL有了足够的领悟,并且欣赏在浏览器的地址栏中输入导航选项。第三,当某人理解了URL的结构时,他们更可能连接它、与朋友共享它、或在电话中报读它。第四,它并不会把你应用程序的技术细节、文件夹、文件名结构暴露给整个公用网,因此,你可以自由地修改底层实现而不会打断输入连接。整洁的URL在早期的框架中难以实现,但ASP.NET MVC默认使用System.Web.Routing工具给出整洁的URL。这使你能够完全控制URL方案及其与应用程序的关系 — 使你能自由地创建对用户有意义和有用的URL模式,而无需符合预定义模式。而且当然,这意味着如果你想,你可以很容易地定义现代的REST风格的URL方案。
建立在ASP.NET平台最好的部分之上
    微软现在的ASP.NET平台为高效开发web应用程序提供了一组成熟的、经充分证明的组件和工具集。首先,也是最明显的,由于ASP.NET MVC是基于.NET平台的,因此你拥有了很大的灵活性,你可以使用任何.NET语言来编写代码、可以访问同样的API特性 — 这不仅仅是MVC本身的特性,而是广泛的.NET类库、以及广泛的第三方.NET包库体系。建议使用C#,可以享用其诸多特性:比如 Lambda表达式,LINQ TO Entities,匿名类型与方法。
    其次,现成的ASP.NET平台特性,如母版页、表单认证、成员、角色、特征、以及国际化等等,可以减少你开发和维护web应用程序的代码量 — 而且这些特性在MVC框架中的使用就像它们在经典的web表单项目中的使用一样有效。一些Web表单内建的服务器控件 — 以及你的早期项目中的自定义控件 — 可以在一个ASP.NET MVC应用程序中被重用(只要它们不依赖于Web表单的专用概念,如视图状态)。ASP.NET 4.5不仅被紧密地集成到了Visual Studio之中,它也是建立在Win 7、以及Server产品中的IIS web服务器所支持的本地web编程技术。IIS自第7版起,利用对ASP.NET应用程序的特殊处理,可以把.NET托管代码作为其请求处理管道的本地部件,实现了对.NET托管代码的一流支持。由于建立在ASP.NET平台的核心之上,MVC应用程序得到了所有这些好处。通俗一点讲,ASP.NET MVC4站在巨人肩膀上,利用了ASP.NET所有最好的东西!
现代API
    ASP.NET MVC 3是针对.NET 4而建立的,因此它的API可以充分利用最新语言和运行时创新 — 包括扩展方法、lambda表达式、匿名及动态类型、以及LINQ等等。许多MVC框架的API方法和编码模式与早期平台相比,遵循了一种更清晰、更富表现力的写作方式。
 
谁该使用ASP.NET MVC?
    如同任何新技术一样,因为其存在就必须使用它,这并不是一个充分的理由!当选择一个web应用程序框架时,你也应当考虑:在技术层面上,你团队的技能、移植现有项目所涉及的工作、你的关系、以及信心等方面的因素。我们已经详述了传统ASP.NET Web表单的弱点与局限性,以及ASP.NET MVC如何克服了这些问题的许多方面。但这并不意味着Web表单的消亡,微软反复声明,对这两种技术都会积极地加以发展和支持,而且也没有要引退Web表单的计划。在某些方面,你对两者的选择是一种开发理念方面的事情。
   # Web表单的观念是UI应当是状态化的,并最终在HTTP和HTML之上添加一个复杂的抽象层,用视图状态和回递来创建状态化的效果。这使得它适合于“拖-放”式Windows表单风格的开发,其间,你把UI部件拖放到一个画布上,并在其中填写其事件处理器的代码。
   # MVC采纳了HTTP真正的无状态本性,遵循而不是违抗它。它要求你理解web应用程序实际上是如何工作的,在理解的提前下,它提供了一种简单的、功能强大的、现代的方法,以整洁的代码来编写web应用程序,这些代码总是易于扩展和维护,并且免除了离奇的复杂性和令人痛苦的限制。这方面做的最极端的是Sinatra。
     当然也有Web表单至少与MVC一样、甚至更好的一些情况。明显的例子是开发小型的、企业内部型应用程序,它大量的工作是把网格直接绑定于数据库表或通过向导对用户进行引导。当你不必担忧带宽消耗或搜索引擎优化时,Web表单的拖-放式开发优点可能胜过它的弱点。另一方面,如果你正在编写用于Internet的应用程序,或大型intranet应用程序等高端企业应用项目,那么你会被MVC所提供的带宽效率、更好的浏览器兼容性、以及更好的自动测试支持等所吸引。
     Rails已经成为与其它web平台进行比较的一个基准。微软.NET世界的开发者和公司会发现ASP.NET MVC易于使用和学习,而工作于Linux或Mac OS X上的Python或Ruby开发者和公司会发现Rails更容易。从Rails迁移到ASP.NET MVC是不可能的,反之亦然。两种技术之间有一些本质上的差别。Rails是一种整体开发平台,意即,它处理整个技术堆栈,从通过ORM进行数据库源控制,到用控制器和动作处理请求,所有一切都可以用内建的自动测试工具来完成。       
    ASP.NET MVC框架关注于以MVC模式用控制器和动作来处理web请求。它不具有内建的ORM工具、内建的自动测试工具、或管理数据库迁移的系统 — 这是因为.NET平台已经对这些功能包含了广泛的可选范围,而且你可以使用其中任意一种。例如,如果你正寻找一个ORM工具,你可以用NHibernate、Subsonic、微软的实体框架、或其它任意一种成熟可用的解决方案。这就是宽松的.NET平台 — 尽管它实际意味着这些组件确实并未像Rails那样集成到ASP.NET MVC之中。ASP.NET MVC还在高频率的改进,比如:引入Razor视图引擎。以前的MVC版本一直依赖于ASP.NET的视图引擎,它依赖于ASP.NET的<%和%>代码块 — 如果你曾做过任意一种ASP.NET开发,你肯定看到过这种运用。Razor引擎用@字符代替了传统的代码块。这种新符号能更快地书写、更快地编译、具有更灵活的特性,并比旧的视图引擎更易于单元测试。你仍然可以使用以前的方法,但微软团队已经清楚地表明,Raozr是MVC的未来 — 所以,我们都采用Razor。同时,对依赖性注入有更好的支持,而且改善了对JSON数据格式以及对JavaScript的支持 — 包括与jQuery的紧密集成。
 
小结:
     我们看到了ASP.NET MVC平台如何解决ASP.NET Web表单的弱点,以及它的现代设计如何把优势交付给那些想编写高质量、可维护代码的开发者。在下一节,你将看到MVC框架的运转、了解获得所有这些好处的一些简单机制。到第7节,你便做好了以整洁的体系结构、适当的关注分离、自动测试、以及漂亮的最少标记来建立一个真实的电子商务应用程序的各项准备。最后建议,微软:重复的而劣质的可以去除,比如能用LINQ TO Entities就可精简LINQ TO SQL,有Razor视图引擎就可以去除其它的。有动态类型与Var可以精简其它的。等等!
posted @ 2013-05-21 18:19  天山式神剑  阅读(1380)  评论(2编辑  收藏  举报