为什么会出现 ASP.NET 平台下的 MVC 框架?

阅读数:28496 2007 年 12 月 10 日

话题:.NETWeb框架语言 & 开发

Rick Strahl 在他对 ASP.NET 平台下的 Web Form 和 MVC 框架的观察中首先谈到了 Web Forms 的强大之处。他提到,Web Forms 已经被证明是一个非常稳定和成熟的平台。即使在性能要求非常高的情况下,它也不太会出现扩展方面的问题。同时,Rick 还认为从 Web Froms 入门 Web 开发是一件非常容易的事情。 

微软设计了一个完整 Web 开发环境,使得构建 Web 应用有了新的体验,开发人员只需在一个可视化设计器中拖放控件、并且在表单中设置属性即可。与此同时,开发人员可以编写代码来响应事件,这使得对于程序逻辑的操作变得非常直观,就好像并非在开发一个 Web 应用一样。Web Forms 模型提供了一个高度抽象的框架,使得入门变得非常容易。但是它也容易造成一些问题,因为它在很多方面将开发人员和低端的 Web 机制隔离开来。我稍候将回过来再谈一下这个次要的问题。

他在总结中谈到,这个框架有着非常强大的扩展能力,并且肯定了它对自定义控件这一产业所做出的贡献(可能 ASP.NET 控件厂商比其他平台下的总和还要多)。

对“高度抽象”进行了褒扬之后,Rick 开始阐述它的缺点。

这既是一种幸运也是一个祸根。Web Forms 让开发人员能够轻松地拖放控件,并且通过响应页面和控件的各种事件来快速开发 Web 应用。这一点很不错,但是首先这种高度的抽象使很多开发人员完全忽略了——甚至从没有了解过在这背后 HTML 是如何运作的。这往往会产生无法通过校验的 HTML 代码,或者是一些非常冗余,难以管理的 HTML 布局,这对于页面设计人员非常不友好。同时,如果没有合理控制 ViewState 的话,你很容易得到一个包含大量 ViewState 的页面,它的尺寸远远超过所需的内容,最终使得页面打开异常缓慢。

Web Forms 框架的缺点之一,就是微软在这个抽象背后构建了一个非常复杂的引擎,它给页面的执行过程带来了许多的负面效应。如果你曾经构建过包含大量组件的复杂页面,就会发现某些时候要协调好数据绑定,页面生成等事件的顺序,并且在页面的生命周期中选择恰当的时间来设置不同的控件是一件非常困难的事情。你是否曾经在 Init、Load 或者 PreRender 事件中加载过数据?你是否在 PostBack 事件中进行过赋值?Web Forms 需要服务器端的一个独立的表单中进行操作,因此你可能无法轻易地将它分解成小的逻辑单元。在一些复杂情况下,事件处理程序会变得非常庞大,你很难对它们的工作进行重构,最终你会得到许多难以维护的代码,并且几乎无法进行测试。

他继续详细讨论了 ViewState,事件管理和 PostBack 机制的问题。对于这些内容还没有做到了如指掌的 ASP.NET 开发人员应该通过文章内容再努力学习一下。

有个问题可能会使非.NET 平台的开发人员感到非常惊讶:我们很难在设计期间就确定一个控件的 ID。由于文档中少有提及的命名容器链(Naming Container Chain)存在一定的缺陷,我们只有在运行时期才能知道“txtPassword”控件最终会获得一个形如“PublicSiteTemplate1_ctl00_txtPassword”的 ID。而在使用其它技术开发的普通页面中,这应该是一个相对较短的 ID。

含糊不清的控件 ID 以及 ViewState 对于如今的 Web 2.0 站点来说都是严重的问题。唯一不会受到 ViewState 带来的负面影响的框架是 ASP.NET AJAX,但这还是一个不成熟的类库。(译者注:事实上,如果您使用了 ASP.NET AJAX 中的 UpdatePanel 控件,在客户端与服务器端交互的过程中依旧需要传递页面上所有的 ViewState。另外,2006 年最佳个人定制页面网站www.pageflakes.com,也是基于当时的 ASP.NET AJAX 框架开发的,并且集成到.NET Framework 3.5 中的 ASP.NET AJAX 又在各方面有了更进一步的改进,如果武断地称之为一个不成熟的类库未免有失偏颇)。

对我来说,Microsoft AJAX 总体上无法成为我的首选客户端框架。它体积很大,并不十分模块化,而且对于客户端开发人员来说,一个本应该包含更多有用核心功能的客户端脚本框架,它提供的功能又非常有限。如果你将它和 jQuery,Prototype,MooTools 等包含强大功能的类库相比,感觉 Microsoft AJAX 严重缺乏一些在实际使用中有用的功能。同时,它包含的控件构建模型又显得死板而复杂,这些都无法成为选择 Microsoft AJAX 的理由,除非你想使用 UpdatePanel 或者 AJAX Control Tookit 中的服务器端控件。

接着 Rick 又谈到了 Web Forms 开发人员很容易将业务逻辑和表现层逻辑混合在一起。虽然使用 Web Forms 也可以将两者很好的分开,但是做到这点需要遵守相当数量的规则。

对于专业人员来说,Web Forms 难以测试是一个更大的问题。Web Forms 几乎无法做到自动测试,一部分原因是由于我们很难模拟 Context、Response 和 Session 对象,至于其他的原因还有例如我们很难处理它的事件驱动模型等。

MVC 框架完全将这些缺点抛至一边,因为它舍弃了 Page 类和其他相关的负担。Rick 是这样描述它的:

微软创建了另一种 Http Handler 来实现 MVC 框架,所以它完全与 Page 类无关,也避免了很多 Web Forms 框架所带来的复杂性。MVC 框架的一个关键特性是提供了一种为特定任务生成内容而创建自定义视图(View)的能力。而控制器(Controller)负责使用各种模型来完成应用的核心任务,然后为视图提供生成页面内容所需的数据。例如,我们很容易想到为 RSS 或者其它 XML 输出的数据,亦或是类似登陆框或者出错页面来编写可复用的视图。然而,在默认情况下,生成视图的输出内容依旧使用了 ASPX 页面:ViewPage 类。它基于 Page 类,但是并不会直接被 HTTP Handler 执行,而是被 MVC 引擎用作内容生成器,这比在完整的 Web Forms 框架中运行传统的 ASPX 页面要显得轻量了许多。

我们还是可以使用 Web Forms 框架中的部分控件和一些技巧,不过前提条件是它们不能依赖 Post Back。和在页面中使用控件的传统开发方式不同的是,开发人员会发现他们需要使用大量的内联代码,就好像传统的 ASP 应用一样。

MVC 模型在工作时是通过 URL 来选择应该执行哪个指定的控制器方法,并且任何的操作都会被引导至控制器中的特定方法。微软开发的引擎使用了类似 Ruby(译者注:确切的说应该是 Rails 框架,Ruby 只是一种开发语言)的机制来解析干净的 URL(例如http://localhost/Customers/Show/1),并且根据 URL 的格式将它们引导至特定的控制器,这种引导机制——就像 MVC 框架中的大部分东西一样——能够被很轻易地重新定义,这样你就能够使用不同的 URL 语法来将引导至特定的控制器。

同时,Rick 发现一些有趣的东西,因为事物在过去十年中的发展形成了一个循环。

Web Forms 模型曾经是.NET 平台下 Web 开发最钟意的方式,在这个讨论中谈到这点显得多少有些有趣。事实上,我觉得有些讽刺的是,MVC 框架在一定程度上回到了传统的 ASP 风格,那便是直接使用脚本来手动生成 HTML 的开发方式,而现在只是提供了一种更为严格的做法来将这种开发方式和代码逻辑区分开来。我还记得在早些时候,那些 ASP.NET 的疯狂追随者们是多么不屑使用内联的脚本标签,或者使用显式的 URL 而不是 PostBack 来进行开发的做法,而其中的一些人现在又毫不犹豫地张开双臂去迎接 MVC 框架,这难道不讽刺吗?

现在要确定 MVC 框架是否真正满足大多数 Web 开发人员的需要还为时过早。从现在所表现出来的结果上看,即使是开发简单的页面,MVC 框架也需要大量的代码。我看过早期版本的 MVC 框架,但是并不清楚如何才能有效地编写一些更加复杂的页面,除非编写大量的选择语句来引导代码,我很难确定究竟页面上的哪一部份需要更新。以前我曾经开发过几个和 MVC 框架运作方式比较接近的 Web 开发框架,根据我的经验,它们总能很轻易的用于简单的页面开发,但是一旦页面上需要出现各种不同的、且相互独立的组件时,这些做法都逐渐出现问题了。使用基于无状态的控制器的做法来管理复杂度高的应用,要比目前 Web Forms 框架提供的功能要困难许多。至于这个框架会如何发展,以及最终会形成什么样的模式来处理复杂任务,我们都还需要拭目以待。如果关注一些 Java 或.NET 平台下已经出现一段时间的 MVC 开发方式并加以比较,则可能会带来不小的帮助。

 最后,Rick 是这样总结的:

到目前为止,我还没有打算将所有的希望押在一个新出现的,还没有被证明成功的框架,因为这好比连小孩和洗澡水一起倒了。Web Forms 还是有许多优点,微软现在只是决定尝试一些新的事物,但这并不意味着我们必须完全转向它们。毕竟 MVC 框架出现的时间还不够长,现在还不能算作久经考验。虽然 MVC 框架很快就会吸引一批开发人员——但是对于其余像我们这样的人,微软还必须给出一个无比强大的框架,它至少需要能够在灵活性,扩展性和可用性等方面和 Web Forms 相媲美。有趣的事情还在前面,我也会兴致勃勃地关注它们……
查看英文原文:Why MVC for ASP.NET?
译者简介:赵劼 (Jeffrey Zhao,网名老赵),毕业于复旦大学软件学院,曾任职于微软中国研发中心,现任某创业团队架构师。有 8 年左右的 Web 应用开发和 5 年左右的.NET 应用程序开发经验,对 ASP.NET 企业应用开发与客户端技术(如 JavaScript 和 AJAX 等)有较为深入的理论基础与实践经验,另外,他对 SOA、重构以及程序员能力与修养等相关问题也有着浓厚的兴趣,并且非常希望能够写程序到 60 岁。他的博客为:http://jeffreyzhao.cnblogs.com