ASP.NET是一种建立动态Web应用程序的技术。它是.NET框架的一部分,可以使用任何.NET兼容的语言编写ASP.NET应用程序。相对于Java、PHP等,ASP.NET具有方便性、灵活性、性能优、生产效率高、安全性高、完整性强及面向对象等特性,是目前主流的网络编程技术之一.它可以让开发者快速高效的创建应用程序而不必关注Http,Html,Javascript等底层的详细信息。随着越来越多的企业将网站升级为APS.NET,web应用程序的复杂性不断增加,即使当初MS推出ASP.NET的时候,如何强调codebehind的优势,但是它在架构上回避不了一个问题:如果全部codebehind的话,.cs势必需要担负起同时处理事务逻辑和视图各方面属性的任务。一个是对逻辑的控制,另一个是对视图(服务器控件)的控制。 当预期超过了一定的阈值可能使的Web Forms不再是一种最佳的选择。由于它牺牲掉一个优秀模型的某些方面,比如可维护性,可读性,可测试性以及对HTMl的可控性,越来越多的人认为ASP.NET Web Forms model不太理想。
ASP.NET MVC是创建APS.NET应用的一种新的平台,和传统的 Web Forms一样运行于ASP.NET run-time environment。MVC专注于用户浏览页面时的行为,并且具有不同的试图引擎来控制生成的标记。在标准的ASP.NET runtime environment之上,MVC创建了自身的shell,该shell一端与ASP.NET run-time objects(例如:request,HttpContext)相连,另一端将它本身对象集暴露给内部的组件,非常有意思的是对象集是被注入到ASP.NET MVC runtime shell中的。因此它具有很高的可测试性。MVC是怎么样处理请求的呢,再这之前,我们先了解下ASP.NET的运行机制。
从开发者的角度来看,Web Forms和MVC是两种不同的开发框架,但是它们具有很多共同点。特别是它们运行于相同的运行时环境:the standard ASP.NET runtime environment.
通常来讲,运行时环境就是一组托管在Web服务器上的组件,用来处理到达服务器的Request并向客户端返回Response。ASP.NET Web Forms and ASP.NET MVC运行时机制是相同的,这就意味着ASP.NET pages and ASP.NET MVC可以同时存在于一个应用程序中。尽管底层机制是相同的,但是ASP.NET MVC and a Web Forms处理request的步骤却完全不同。MVC在ASP.NET runtime之上有自己的run-time shell并且实现自己的管线来处理它获得的请求。
我们通过创建虚拟目录将资源Host到IIS下,原则上,我们可以通过IIS访问置于虚拟目录下的所有Resource,这部仅仅包含一些静态资源文件,比如图片、纯Html文件、CSS、JS等等,也包含一些需要动态执行的文件,比如aspx,asmx等等,我们还可以将Remoting和WCF Service Host到IIS下。对于这些静态的文件,IIS直接提取对应的文件将其作为Http Response返回给Client,但是对于这些需要进一步处理的动态执行的文件,IIS必须将Request进一步传递给对应的处理程序,待处理程序执行完毕获得最终的Http Response通过IIS返回给Client。对于IIS来说,这些处理程序通过ISAPI Extension来体现。对于基于ASP.NET的Resource,其对应的ISAPI Extension为ASP.NET ISAPI,通过一个aspnet_isapi.dll承载。IIS的Metadata database维护着一个称为ISAPI Extension Mapping的数据表,负责将不同类型的Resource影射到对应的ISAPI Extension.
IIS5.x
在IIS5.x中,web服务和ASP.NET应用是分离开来的。IIS5.x运行在一个inetinfo.exe的进程中,InetInfo.exe是一个Native Executive,并非一个托管的程序。IIS分析Request的目标资源文件的扩展名(这里是aspx),通过ISAPI Extension Mapping获知对应的ISPAI为ASP.NET ISAPI,于是加载aspnet_isapi.dll。到此为止,该Request的处理交由ASP.NET ISAPI处理。ASP.NET ISAPI会创建一个叫做aspnet_wp.exe的Worker Process(如果该进程不存在的话),在aspnet_wp.exe初始化的时候会加载CLR,从而为ASP.NET Application创建一个托管的运行环境,在CLR初始化的使用会加载两个重要的dll:AppManagerAppDomainFactory和ISAPIRuntime。通过AppManagerAppDomainFactory的Create方法为Application创建一个Application Domain;通过ISAPIRuntime的ProcessRequest处理Request,进而将流程拖入到ASP.NET Http Runtime Pipeline的范畴,ASP.NET Http Runtime Pipeline对Http Request的处理是一个相对复杂的过程,相关的介绍会放在本篇文章的下一部份。在这里我们可以把它看成是一个黑盒,它接管Request,最终生成Html。
当IIS5.x运行的进程和asp.net运行的进程相互独立时,它们之间采用了Named Pipe来进行通讯。IIS5.x主要应用在Windows XP或Windows 2000操作系统中。
IIS6.0
IIS7.0
HTTP运行期处理客户端应用程序(例如Web浏览器)进入的一个Web请求,通过处理它的应用程序的适当组件路由请求,然后产生响应并发回提出请求的客户端应用程序。
进入的HTTP Web请求最先由IIS Web服务器接收到,它在此请求基于ASP.NET已注册处理的扩展名传送到ASP.NET ISAPI上。
HTTP运行期首先创建一个HttpContext对象的实例,它包含了当前正在处理的请求信息,接着创建在处理逻辑中涉及到的所有其他组件都可以使用的上下文对象。HttpContext实例提供了对请求对象(HttpRequest类的实例)和响应对象(HttpResponse类的实例)的访问。
HttpContext
HttpContext体现当前Request的上下文信息,它的生命周期知道整个Request处理结束或者处理超时。通过HttpContext对象我们可以访问属于当前Request的一系列常用的对象:Server,Session,Cache,Application,Request,Response,Trace,User,Profile等等。此外我们可以认为将一些数据放在Items属性中作为状态管理的一种方式,不过这种状态管理和其他一些常用的方式,比如Session,Cache,Application,Cookie等,具有根本性的不同之处是其生命周期仅仅维持在当前Request的Context中。
HttpApplication
就像其名称体现的一样,HttpApplication基本上可以看成是真个ASP.NET Application的体现。HttpApplication和置于虚拟根目录的Gloabal.asax对应。通过HttpApplicationFactory.GetApplicationInstance创建一个基于Gloabal.asax的HttpApplication对象。在HttpApplicationFactory.GetApplicationInstance方法返回创建的HttpApplication对象之前,会调用一个名为InitInternal的内部方法,该方法会做一些列的初始化的操作,在这些初始化操作中,最典型的一个初始化方法为InitModules(),该方法的主要的目的就是查看Config中注册的所有HttpModule,并根据配置信息加载相应的Assembly,通过Reflection创建对应的HttpModule,并将这些Module加到HttpApplication 的_moduleCollection Filed中。
HttpApplication本身并包含对Request的任何处理,他的工作方式是通过在不同阶段出发不同Event来调用我们注册的Event Hander。
HttpModule
我们上面提到HttpApplication就是一个ASP.NET Application的体现,HttpApplication本身并不提供对Request的处理功能,而是通过在不同阶段出发不同的Event。我们能做的只能是根据我们具体的需求将我们的功能代码作为Event Handler注册到需要的HttpApplication Event上面。注册这些Event Handler,我们首先想到的肯定就直接在HttpApplication对应的Global.asax中定义我们的EventHandler好了。这是最直接的办法,而且Global.asax提供一个简洁的方式是我们的实现显得简单:不需要向一般注册Event一样将Delegate添加到对应的Event上面,而是直接通过方法名称和对应的Event匹配的方式直接将对应的方法作为相关的Event Handler。比如Application_ AcquireRequestState就是AcquireRequestState Event handler。
但是这种方式在很多情况下却达不到我们的要求,更多地,我们需要的是一种Plug-in的实现方式:我们在外部定义一些Request Processing的功能,需要直接运用到我们的Application之中。通过使用HttpModule封装这些功能模块,并将其注册到我们的Application的发式可以很简单的实现这种功能。更多内容参考:http://www.cnblogs.com/jyan/articles/2563794.html
HttpHandler
如果说HttpModule关注的是所有Inbound Request的处理的话,Handler确实关注基于某种类型的ASP.NET Resource的Request。比如一个.apsx的Web Page通过一个System.Web.UI.Page来处理。HttpHandler和他所处理的Resource通过Config中的system.web/handlers section来定义.需要注意的是,我们不但可以单纯地定义一个实现了System.Web.IHttpHandler的Type,也可以定义一个实现了System.Web.IHttpHandlerFactory 的Type。System.Web.UI.Page是一个典型的Httphandler,相信对此大家已经很熟悉了。在最后还说说另一个典型的HttpHandler:System.Web.HttpForbiddenHandler,从名称我们不难看出,它用于那些禁止访问的Resource,现在应该知道了为了Global.asax不同通过IIS访问了吧.
更多内容参考:http://www.cnblogs.com/jyan/articles/2563801.html
图中可以初步看出一个HttpRequest是如何被ASP.NET和ASP.NET MVC框架执行的:经过IIS和ASP.NET处理后,Core Routing会首先根据URL匹配物理路径上的文件,如果不能匹配则由核心路由模块执行路由,路由被匹配后,MvcRouteHandler会将这个请求“带入”MVC框架,执行Controller和Action,Action可以直接注入response,或者更平常的是返回一个ActionResult,ActionResult的ExecutedResult方法将被调用,如果是个ViewResult(继承自ActionResult),则会使用WebFormViewEngine转化一个Html,并注入到response。
下图是Web Forms与MVC中运行时环境,可以看出,MVC运行时环境是原始ASP.NET运行时环境的定制版本。
[参考]http://www.cnblogs.com/artech/archive/2007/09/13/891266.html