首页 > 代码库 > ASP.NET底层原理
ASP.NET底层原理
上图基本上演示了IIS 6整个处理过程。在User Mode下,http.sys接收到一个基于aspx的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。WAS(Web Administrative service)根据这样一个mapping,将存在于某个Application Pool Queue的request 传递到对应的worker process(如果没有,就创建这样一个进程)。在worker process初始化的时候,加载ASP.NET ISAPI,ASP.NET ISAPI进而加载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。
ISAPIRuntime会首先创建一个ISAPIWorkRequest对象,对请求报文进行了简单的封装,并将该ISAPIWorkRequest对象传递给HttpRuntime。
HttpRuntime会根据ISAPIWorkRequest创建用于封装Http请求上下文的对象HttpConetxt。
HttpContext主要包括HttpRequest(当前请求)和HttpResponse(服务器响应)
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)]public int ProcessRequest(IntPtr ecb, int iWRType){ IntPtr zero = IntPtr.Zero; if (iWRType == 2) { zero = ecb; ecb = UnsafeNativeMethods.GetEcb(zero); } //创建了ISAPIWorkRquest空对象 ISAPIWorkerRequest wr = null; try { bool useOOP = iWRType == 1; //通过ecb句柄创建了ISAPIWorkRequest对象 wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP); wr.Initialize(); string appPathTranslated = wr.GetAppPathTranslated(); string appDomainAppPathInternal = HttpRuntime.AppDomainAppPathInternal; if ((appDomainAppPathInternal == null) || StringUtil.EqualsIgnoreCase(appPathTranslated, appDomainAppPathInternal)) { //IsapiRuntime把WR交给了HttpRuntime HttpRuntime.ProcessRequestNoDemand(wr); return 0; } HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged, SR.GetString("Hosting_Phys_Path_Changed", new object[] { appDomainAppPathInternal, appPathTranslated })); return 1; } catch (Exception exception) { try { WebBaseEvent.RaiseRuntimeError(exception, this); } catch { } if ((wr == null) || !(wr.Ecb == IntPtr.Zero)) { throw; } if (zero != IntPtr.Zero) { UnsafeNativeMethods.SetDoneWithSessionCalled(zero); } if (exception is ThreadAbortException) { Thread.ResetAbort(); } return 0; }} ISAPIRuntime
HttpRuntime通过HttpApplicationFactory获取一个新的或现有的HttpApplication对象。
private void ProcessRequestInternal(HttpWorkerRequest wr){ Interlocked.Increment(ref this._activeRequestCount); if (this._disposingHttpRuntime) { try { wr.SendStatus(0x1f7, "Server Too Busy"); wr.SendKnownResponseHeader(12, "text/html; charset=utf-8"); byte[] bytes = Encoding.ASCII.GetBytes("<html><body>Server Too Busy</body></html>"); wr.SendResponseFromMemory(bytes, bytes.Length); wr.FlushResponse(true); wr.EndOfRequest(); } finally { Interlocked.Decrement(ref this._activeRequestCount); } } else { HttpContext context; try { //通过wr创建了上下文对象 context = new HttpContext(wr, false); } catch { try { wr.SendStatus(400, "Bad Request"); wr.SendKnownResponseHeader(12, "text/html; charset=utf-8"); byte[] data = http://www.mamicode.com/Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>"); wr.SendResponseFromMemory(data, data.Length); wr.FlushResponse(true); wr.EndOfRequest(); return; } finally { Interlocked.Decrement(ref this._activeRequestCount); } } wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, context); HostingEnvironment.IncrementBusyCount(); try { try { this.EnsureFirstRequestInit(context); } catch { if (!context.Request.IsDebuggingRequest) { throw; } } context.Response.InitResponseWriter(); //通过HttpApplicationFactory获取HttpApplication实例 IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context); if (applicationInstance == null) { throw new HttpException(SR.GetString("Unable_create_app_object")); } if (EtwTrace.IsTraceEnabled(5, 1)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, applicationInstance.GetType().FullName, "Start"); } if (applicationInstance is IHttpAsyncHandler) { IHttpAsyncHandler handler2 = (IHttpAsyncHandler) applicationInstance; context.AsyncAppHandler = handler2; //执行HttpApplication的BeginProcessRequest方法 handler2.BeginProcessRequest(context, this._handlerCompletionCallback, context); } else { applicationInstance.ProcessRequest(context); this.FinishRequest(context.WorkerRequest, context, null); } } catch (Exception exception) { context.Response.InitResponseWriter(); this.FinishRequest(wr, context, exception); } }}HttpRuntime