[转贴一]
使用ASP.NET MVC框架,创建默认项目,第一直观感觉就是地址都是Rewrite过的。对源码和配置文件稍加分析不难看出,MVC使用了httpModules来拦截地址请求,具体用到了System.Web.Routing类库(MVC2中,MVC1怎么用的忘记了。)而这部分类库被包装在.NET Framework3.5 SP1中,MVC2需要SP1支持也就理所当然了。SP1提供的System.Web.Routing类库可以方便地进行地址请求拦截,对编码处理方面也很优秀。UrlRoutingModule类拦截请求,在这之前,Application_Start的时候,会给RouteTable的全局对象一个拦截的设置。而这个设置使用RouteCollection对象进行保存,MVC对这个类进行了扩展——RouteCollectionExtensions。这些可以不考虑,接下来,当用户访问页面时,UrlRoutingModule类拦截请求,在RouteTable中查看是否符合规则,符合的话,就会调用MvcHandler,这个调用在httpHandlers配置节点被注册,条件是地址符合“*.mvc”规则。MvcHandler的ProcessRequest方法就会调用Controller来执行。事实上整个过程都是黑盒子,用户感觉不到。在Controller中某方法执行后,返回结果,再进入具体的aspx页面。
分析了MVC的工作工程,就可以对比其与WebForm的区别了。我们知道,MVC模式的业务被放置到Controller中去执行,而aspx页面只负责显示。那么在MVC中的业务实际执行时间被提前到了HttpMolde中,而WebForm的请求只在httpHandler容器中被执行。也就是说MVC中Controller与View的分离是使用的ASP.Net请求管道隔离的,这样的话无疑在不影响效率(一次请求,而Response.Redirect是二次请求)的情况下达成了代码的逻辑层次的分离。
图1 MVC工作模型
MVC工作的优点是显然的,更加有利于理解分层逻辑,把握代码的层次感。Controller到aspx页面之间的过程,已经被框架隔离。至于Controller或者View页面与Model调用的过程,还是需要自己来把握。ASP.NET的MVC框架实现了Controller代码的单独管理。
而看WebForm开发模型,则只在HttpHandler容器中执行,对其进行分层,在大的方面缺乏支持,而只能依靠逻辑上分离。并不是不能分离,而是由一定的局限性。HttpHandler的拦截,是跟访问后缀名有关的。当请求一个页面时,那就是一个Handler,而WebForm模型实现显示与逻辑分离,才有的是WinForm的事件驱动。显然,事件必须被注册到页面里,比如Button1_Click这样的代码。而在Button1_Click执行之前,Page_Load方法会被执行。
显示代码被写入Page_Load方法中,那么就会造成需要写额外的废代码,比如if (!Page.IsPostBack)这样的判定。而在Button1_Click执行后需要显示的部分,则比较难处理,写出另一个方法,也是必须要在Button1_Click里调用的。替代的解决方案是使用Response.Redirect,在一个aspx页面中处理逻辑,处理完就跳转到另外一个显示的页面。这样做的坏处是,在两个页面中数据很难共享,而跳转是通过标记302来实现,因此多一次请求。而另外还可以通过Server.Execute,Server.Transfer或者Context.RewritePath这样的处理方式,则两个页面转换是在服务器端完成,可以共享数据,可以说和MVC框架的处理方式大同小异,缺点是需要手动配置这些重新定向的属性。
从以上分析可以看出,MVC框架具有很强的优越性,而WebForm也不是一无是处,在简单的应用中更加容易开发。WebForm也是可以实现和MVC一样的分层方式,只是处理时需要多写一些代码而已。而我认为,在用WebForm开发分层遇到的最大问题是页面与页面之间数据的传递问题,而掌握好WebForm中使用服务器端跳转的应用技巧(Server.Execute,Server.Transfer或者Context.RewritePath)进行开发就可以解决数据传输问题,ASP.NET MVC与WebForm比较起来,WebForm更容易理解,不会产生复杂的配置,也是一个很不错的选择。
[转贴二]
MVC纵向切割了开发过程中的代码,从服务器到浏览器层层分离,层次之间耦合度很低,因为它是顺着底层的开发脉络进行封装,所以有利于开发者对整个程序过程流转的理解。但是MVC有一个非常大的缺点,这个缺点是和整个软件发展思路相背离的,那就是它无法封装、无法封装所以无法被重用。有谁看到过mvc下面的组件?有的只是一个个现成的案例,然后拿来修改。因为一个组件肯定牵涉到控制和显示,但是mvc的开发这两个层次是分离的。MVC只适合轻量级的开发,桌面开发是极少用到mvc模式的。然而web开发恰恰就是轻量级,至今所有的web开发都是轻量级的,因为网络硬件条件的限制,不需要也无法做到非常复杂的逻辑。这也是MVC非常非常适合web开发的原因。
WebForm是微软前面一套web开发的机制。它横向切割了代码,控制和显示是封装在一起的。它从开发者思维逻辑上而不是实际情况上对代码进行封装,开发webform容易上手的原因也就在此了,但这个不利于开发者对底层程序流转机制的理解。WebForm中view和controller是放在一起的,WebForm一出现后,随之而来的是大量的组件诞生,这是mvc模式下看不到的。微软的经验之一是硬件发展很迅速。代码的封装是靠牺牲运行效率来提高开发效率,牺牲的运行效率通过提高硬件性能来解决。但微软在webform上犯了经验主义的错误,这个经验不适合网络硬件,网络硬件要考虑兼容性而且是国家的基础设施,更新的灵活性远比单机要差。大量的组件因为硬件的瓶颈无法给WebForm带来什么优势。在发展了几年webform后,微软觉得这样下去不行,等到网络硬件发展起来不知道到猴年马月了,所以就抄了一下成熟的mvc,通过Entity Framework做数据库和对象的映射,很明显,它是为了充当mvc中那个Model。通过mvc来控制和展示。
webform生产关系是比mvc先进的,但是它不适合现在的网络设施生产力,如果要适合说不定要10年后。webform和mvc很好的印证了生产关系必须适合生产力,即使强大如微软也无法改变客观规律。
[转贴三]
ASP.NET MVC :从ASP.NET WebForm到ASP.NET MVC技术上的共用和差异
关于WebForm与MVC的讨论,年初的时候已经有一段很长时间的讨论了。我无意再去争论哪种架构模式更适合我们做开发,不管是哪个领域,技术的存在都有其不同的历史意义和市场价值。我更关注的是,在合适的机会去掌握更多的技术,从技术实现的角度来寻找当前阶段最为顺手的一种做事方法。所以请注意,在这里不讨论WebForm与MVC的优劣,适用场景。在这里只有ASP.NET WebForm与ASP.NET MVC,同样属于ASP.NET框架下的两种不同的Web开发技术,是如何充分发挥ASP.NET平台的强大功能,以及对于掌握ASP.NET WebForm的开发人员,转向ASP.NET MVC架构的学习成本。这就是我本篇文章的立意所在,同时我也是希望为我之后的几篇MVC系列文章提供一些注脚和铺垫。
之前,从事ASP.NET开发,在没有特殊说明的情况下,指的就是ASP.NET WebForm的开发。之前ASP.NET技术的发展,直接就体现在WebForm技术上的进步。在ASP.NET MVC 出现之后,之前大家所掌握的ASP.NET技术对于ASP.NET MVC仍然有效,并且是最基础的部分。包括:页面处理流程,Web请求上下文对象,Web配置系统,公用性的组件模块,部分的服务器控件等等。我想从这几大块来详细阐述ASP.NET MVC对于ASP.NET技术的继承:
页面处理流程:ASP.NET MVC 的页面处理流程仍然是在ASP.NET原有的处理流程上的扩展,在在上游的请求通道不变的前提下,通过特定的IHttpModule和IHttpHandler来处理ASP.NET MVC的请求。与WebForm页面处理不一样的地方就在于,在WebForm中,每一个页面都是一个IHttpHandler实例,页面的事件流程就是从IHttpHandler的ProcessRequest(HttpContext httpContext)方法开始。而在ASP.NET MVC中,所有的Controller都并不是IHttpHandler的继承实例,它的Action是在MvcHandler中被执行的,当然我们也可以自定义是MvcHandler。
Web请求上下文对象:在ASP.NET MVC中,处理请求的线程模型没有改变。请求的上下文对象,与原有的ASP.NET WebForm仍然是共用的。
Web配置系统:ASP.NET MVC仍然使用原有的配置系统,在Web.config中只是部分的配置节点不适用于ASP.NET MVC,比如页面访问授权配置。
公用性的组件模块:在ASP.NET MVC中,包括Membership,healthMonitoring,httpModule,trace在内的内置和自定义的组件模块仍然是继续可用。
部分服务器控件可用:首先,最为明显的是我们使用的是.aspx页面作为MVC的View。虽然后缀仍然为.aspx,但是它的意义已经不再是一个可执行的页面文件了,不再是一个纯粹意义上的IHttpHandler。但是它仍然是继承于原有的Page基类。在ASP.NET MVC中,将它作为View来展示,仍然以ProcessRequest为入口来执行页面,也就意味着除了回发事件的相关事件和函数不会被执行外,页面的执行事件流程仍然是有效的。以此,如果不考虑服务器控件的性能和其它因素影响,我们仍然是可以使用大部分的服务器控件,当然用不用取决于你。
以上是我总结到的一些ASP.NET MVC对ASP.NET原有技术的继承,但是做为ASP.NET技术的发展,有很多东西是本身就是乏善可陈的,不说,也应该知道就是那样。但是说出来,更有助于大家来区分ASP.NET,(ASP.NET)WebForm,ASP.NET MVC(为什么WebForm前面的ASP.NET加括弧呢?大家来说说原因)这三者的概念区别和关系。
下面我还想来说说,ASP.NET MVC较之前的ASP.NET(WebForm)开发技术在实践上有哪些比较明显的区别:
.aspx文件,已经不再是一个可被独立请求的页面了。你不能对它从物理上进行权限控制。
我们的少用服务器控件了。我们仍然可以使用,你完全可以不考虑runat='server'的性能影响。但是并不保证所有的服务器控件都可用。可能还有其它的原因让你选择不使用服务器控件。
我们没有PostBack和页面回发事件机制了。提交表单我们基本使用Web的原生方式了,传输的数据量也更为合理。
我们少用ViewState了。少用,意味着我们还是可以用的。只是由于MVC架构的限制,我们在ViewState存的值并不会被序列化到客户端去,它有效性是在一次请求的上下文中。在某些特定的场合内,ViewState还是能发挥它的余热,并且并不影响性能。
要处理一个用户的自定义请求,比如RSS请求。我们不再需要定义一个IHttpHandler或特定的.aspx页面。处理用户的每个请求都只是在一个Controller的Action函数当中,在Action函数中,你可以输出View,可以输出JSON字符串,还可以输出任何自定义格式的文件和输出流。
业务逻辑与UI逻辑从架构上得到了很好的分离,但是你要不想这么做,仍然也是有效的。只是在这种情况下,你还是选择WebForm吧。
ASP.NET MVC和WebForm在很多实现上的统一,是我们已经掌握ASP.NET原有开发模式的开发人员顺利的上手MVC保证。之后陆续会有几篇我在用MVC实践自己一个网站后,对MVC的一些总结和心得。