1、请求到达IIS服务器,IIS根据文件后缀找到对应的ISAPI(Internet Server API)扩展来处理,这个配置可在网站属性里的“根目录”选项卡中的“配置”里看到。可以看到,ashx、aspx配置的都是“aspnet_isapi.dll”,此ISAPI扩展我们便称之为ASP.NET。
2、ASP.NET加载CLR,在CLR初始化的时候会加载两个重要的dll:AppManagerAppDomainFactory和ISAPIRuntime。
3、AppManagerAppDomainFactory在构造方法中创建ApplicationManager对象,create方法调用ApplicationManager的对象方法创建了AppDomain的对象,并在此过程中创建了HostingEnvironment的对象(该对象提供应用程序的物理路径、虚拟路径等信息)。
4、ISAPIRuntime的ProcessRequest方法创建HttpWorkerRequest的对象,来保存请求信息(HttpContext的前身),进而调用HttpRuntime的静态方法ProcessRequestNoDemand而最终在其实例方法(HttpRuntime有一个字段private static HttpRuntime _theRuntime;来保证每个应用程序只有一个HttpRuntime实例) ProcessRequestInternal里创建了HttpContext和HttpApplication对象。在向HttpApplicationFactory申请对象时,若对象不是现成的,才会间接调用HttpApplication的InitialModules方法创建已经配置的module,最后开始走HttpApplication的19个事件,(即管线/Http Pipeline)加工HttpContext。
19个事件中,在PreRequestsHandlerExecute和PostRequestsHandlerExecute两个事件之间,调用了HttpHandler的ProcessRequest方法。自定义的HttpModule可以在HttpApplication对象的任意一个事件上注册方法,HttpApplication则会在顺序触发这19个事件时依次调用在每个事件上注册的方法。通常处理请求时,会在PostAcquireRequestState、PreRequestsHandlerExecute这两个事件上注册,前者是Session已经获得(前提是HttpHandler实现了IRequiresSessionState接口,Page类是通过EnableSessionState="false"来动态觉定是否实现此接口),后者是将要执行HttpHandler的ProcessRequest方法。
系统已经注册的HttpModule、HttpHandler可以参见C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\web.config文件,我们可以看到.config、.cs等文件之所以不能直接访问,是因为都被注册了一个HttpForbiddenHandler。在网站根目录中的web.config注册的HttpHandler优先级要高于系统已经注册的,所以如果如果注册一个HttpHandler,并将path设为“Account/*.aspx”,那么所有访问Account文件夹下的aspx请求都会转到注册的HttpHandler上。
参考: