ASP.NET是如何在IIS下工作的 ASP.NET与IIS是紧密联系的由于IIS6.0与IIS7.0的工作方式的不同导致ASP.NET的工作原理也发生了相应的变化。IIS6(IIS7的经典模式)与IIS7的集成模式的不同IIS6的运行过程分析上图可知在 User Mode 下http.sys 接收到 http request然后它会根据 IIS 中的 Metabase 查看基于该 Request 的 Application 属于哪个 Application Pool 如果该 Application Pool 不存在则创建之。否则直接将 request 发到对应 Application Pool 的 Queue中。每个 Application Pool 对应着一个 Worker Process — w3wp.exe(运行在 User Mode 下)。在 IIS Metabase 中维护着 Application Pool 和 Worker Process 的Mapping。WASWeb Administrative Service根据这样一个 mapping将存在于某个 Application Pool Queue 的 request 传递到对应的 Worker Process (如果没有就创建这样一个进程)。在 Worker Process 初始化的时候加载 ASP.NET ISAPIASP.NET ISAPI 进而加载 CLR。最后通过 AppManagerAppDomainFactory 的 Create 方法为 Application 创建一个 Application Domain通过 ISAPIRuntime 的 ProcessRequest 处理 Request进而将流程进入到 ASP.NET Http Runtime Pipeline。几个知识点:HTTP.SYSKernel的一个组件它负责侦听Listen来自于外部的HTTP请求,根据请求的URL将其转发给相应的应用程序池 (Application Pool)。当此HTTP请求处理完成时它又负责将处理结果发送出去.为了提供更好的性能HTTP.SYS内部建立了一个缓冲区将最近的HTTP请求处理结果保存起来。Application Pool: IIS总会保持一个单独的工作进程应用程序池。所有的处理都发生在这个进程里包括ISAPI dll的执行。对于IIS6而言应用程序池是一个重大的改进因为它们允许以更小的粒度控制一个指定进程的执行。你可以为每一个虚拟目录或者整个Web 站点配置应用程序池这可以使你很容易的把每一个应用程序隔离到各自的进程里这样就可以把它与运行在同一台机器上其他程序完全隔离。从Web处理的角度看如果一个进程死掉至少它不会影响到其它的进程。当应用程序池接收到HTTP请求后交由在此应用程序池中运行的工作者进程Worker Process: w3wp.exe来处理此HTTP请求。Worker Process: 当工作者进程接收到请求后首先根据后缀找到并加载对应的ISAPI扩展 (如:aspx 对应的映射是aspnet_isapi.dll)工作者进程加载完aspnet_isapi.dll后由aspnet_isapi.dll负责加载 ASP.NET应用程序的运行环境即CLR (.NET Runtime)。Worker Process运行在非托管环境而.NET中的对象则运行在托管环境之上(CLR)它们之间的桥梁就是ISAPI扩展。WASWeb Admin Service这是一个监控程序它一方面可以存取放在InetInfo元数据库Metabase中的各种信息另一方面也负责监控应用程序池Application Pool中的工作者进程的工作状态况必要时它会关闭一个老的工作者进程并创建一个新的取而代之。IIS7的运行过程分析上图可知1、当客户端浏览器开始 HTTP 请求一个WEB 服务器的资源时HTTP.sys 拦截到这个请求。2、HTTP.sys 联系 WAS 获取配置信息。3、WAS 向配置存储中心(applicationHost.config)请求配置信息。4、WWW 服务接收到配置信息配置信息指类似应用程序池配置信息站点配置信息等等。5、WWW 服务使用配置信息去配置 HTTP.sys 处理策略。6、WAS为请求创建一个进程(如果不存在的话)。7、工作者进程处理请求并对HTTP.sys做出响应。8、客户端接受到处理结果信息。除了IIS的整体运行方式不同之外IIS7相比IIS6最大的不同之处在于它提供了两种应用程序池管道模式经典模式是与IIS 6或者之前版本保持兼容的一种模式一个典型问题就是在处理ASP.NET这种动态网站的时候它是通过一个所谓的ISAPI程序作为插件的方式来工作的。针对不同的动态应用程序(例如ASP,PHP等)会需要不同的ISAPIInternet Server Application Programe Interface互联网服务器应用程序接口。如图在IIS中打开“处理程序映射”可以看到aspx类型页面的处理程序为aspnet_isapi.dll。下图展示了IIS7经典模式与IIS6的应用程序池管道模式运行原理针对不同的请求会指定不同的ISAPI(dll)进行处理集成模式asp.net不再像IIS6一样只限定于aspnet_isapi.dll中而是被解放出来从IIS接收到HTTP请求开始即进入asp.net的控制范围asp.net可以存在于一个请求在IIS中各个处理阶段。允许我们将ASP.NET更好地与IIS集成甚至允许我们在ASP.NET中编写一些功能例如Module来改变IIS的行为扩 展。集成的好处是不再通过ISAPI的方式提高了速度和稳定性。至于扩展则可以使得我们对于IIS以及其他类型的请求有更多的控制。例如我 们希望静态网页也具备一些特殊的行为。如图如下图在IIS7集成模式中打开处理程序映射可以看到aspx类型页面所对应的不再是一个dll而是一个类型。总结与扩展对于处理ASP.NET应用程序而言IIS6及IIS7的经典模式需要aspnet_isapi.dll来处理而IIS7集成模式不需要aspnet_isapi.dll来处理而可以直接根据文件扩展名找到相应的处理程序接口。例如aspx的处理程序是System.Web.UI.PageHandlerFactory类型。介绍完IIS的工作原理来看一下ASP.NET内部的运行机制。首先看一下IIS处理模型上面介绍IIS工作原理时已经介绍了从发起HTTP请求到响应请求的过程这里主要介绍当请求到达.NET Runtime之后.NET运行时所发生的一系列工作。先看如下的.NET运行时工作序列图1.HTTP请求进入Web服务器后首先由HTTP.SYS来判断请求的页面是否存在如果存在的话将把请求信息转交给.NET Runtime。在这部分实际是完成两个步骤在将请求转交给.NET Runtime的同时将请求信息封存在HTTPWorkRequest类中供其它步骤调用。HttpWorkRequest类在以后的操作中至关重要它第一次将Http请求信息转换为类信息。2.当请求到达.NET Runtime后接下来的操作将会在托管环境中完成这时请求就真正进入了.NET中对请求信息的操作是由.NET的底层类库来实现。首先.NET Runtime将会针对请求信息做两个动作一是准备HostingEnvironment二是调用ApplicationManager类为HTTP请求动态的分配AppDomain并把处理权交给AppDomain。3.HTTP请求进入AppDomain后将由对象ISAPIRuntime来接管一方面经方法ProcessRequest()得到HttpWorkerRequest对象另一方面由方法StartProcessing()生成HttpRuntime对象接下来把处理权交给了HttpRuntime(HttpWorkerRequest对象将作为HttpRuntime方法中的参数被使用)。4.HTTPRuntime接收到Http请求后方法ProcessRequest处理请求。将对第1步中的HTTPWorkRequest类中的信息进行操作具体的实现由ProcessRequest方法实现。内部代码如下[AspNetHostingPermission(SecurityAction.Demand, LevelAspNetHostingPermissionLevel.Medium)]public static void ProcessRequest(HttpWorkerRequest wr){if (wr null){throw new ArgumentNullException(wr);}if (UseIntegratedPipeline){throw new PlatformNotSupportedException(System.Web.SR.GetString(Method_Not_S