首页 > 代码库 > 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
View Code

 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
View Code