在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
ASP.NET那点不为人知的事(一)
ASP.NET
HTTP协议:
我们通过浏览器插件HttpWatch Professional可以清晰看到浏览器和服务器之间的通信内容: 了解了什么是HTTP协议之后,我们在回到先前提出的那个问题,浏览器的请求怎样到达服务器? HTTP.SYS组件
IIS服务器扩展
ISAPI(Internet Server Application Programming Interface)
IIS7处理程序映射ASP.NET的后台辅助进程aspnet_wp.exe
由一张流程图回顾上述浏览器到达服务器的过程ISAPIRuntme.ProcessRequest方法第一个进入ASP.NET
补充:默默无闻的工作者对象HttpWorkerRequest
客户的请求首先会被ISAPIRuntme对象ProcessRequest方法处理
[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); } ISAPIWorkerRequest wr = null; try { bool useOOP = iWRType == 1; wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP); wr.Initialize(); ...... if ((appDomainAppPathInternal == null) || StringUtil.EqualsIgnoreCase(appPathTranslated, appDomainAppPathInternal)) { HttpRuntime.ProcessRequestNoDemand(wr); return 0; } HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged, SR.GetString("Hosting_Phys_Path_Changed", new object[] { appDomainAppPathInternal, appPathTranslated })); return 1; } ...... }
internal static void ProcessRequestNoDemand(HttpWorkerRequest wr) { RequestQueue queue = _theRuntime._requestQueue; wr.UpdateInitialCounters(); if (queue != null) { wr = queue.GetRequestToExecute(wr); } if (wr != null) { CalculateWaitTimeAndUpdatePerfCounter(wr); wr.ResetStartTime(); ProcessRequestNow(wr); } } internal static void ProcessRequestNow(HttpWorkerRequest wr) { _theRuntime.ProcessRequestInternal(wr); } _theRuntime就是HttpRuntime类型的对象,他在HttpRuntime的静态构造函数初始化。 static HttpRuntime() { ...... _theRuntime = new HttpRuntime(); _theRuntime.Init(); AddAppDomainTraceMessage("HttpRuntime::cctor*"); }
private void ProcessRequestInternal(HttpWorkerRequest wr) { ...... else { HttpContext context; try { context = new HttpContext(wr, false); } catch { try { wr.SendStatus(400, "Bad Request"); wr.SendKnownResponseHeader(12, "text/html; charset=utf-8"); byte[] data = 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; } } ...... } } 在进入看看:根据WR,初始化了请求参数的类型HttpRequest对象和处理回应类型HttpReponse对象 internal HttpContext(HttpWorkerRequest wr, bool initResponseWriter) { this._timeoutStartTimeUtcTicks = -1; this._timeoutTicks = -1; this._threadAbortOnTimeout = true; this.ThreadContextId = new object(); this._wr = wr; this.Init(new HttpRequest(wr, this), new HttpResponse(wr, this)); if (initResponseWriter) { this._response.InitResponseWriter(); } PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_EXECUTING); } privatevoid ProcessRequestInternal(HttpWorkerRequest wr) ProcessRequestInternal这个方法很重要,前面分析了它创建了上下文对象HttpContext,接下来分析HttpApplication的创建。 { ..... IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context); ......
internal static IHttpHandler GetApplicationInstance(HttpContext context) { ......return _theApplicationFactory.GetNormalApplicationInstance(context); } GetApplicationInstance方法生成一个默认的HttpApplication对象,HttpApplication实现了IHttpAsyncHandler接口。 调用HttpApplication对象(实现了IHttpAsyncHandler接口)的BeginProcessRequest方法执行客户请求。
OK,回到前一步,再深入一步,进入GetNormalApplicationInstance方法之后,我们看到了HttpApplication对象是如何被创建和初始化: private HttpApplication GetNormalApplicationInstance(HttpContext context) { HttpApplication state = null; ...... if (state == null) { state = (HttpApplication) HttpRuntime.CreateNonPublicInstance(this._theApplicationType); using (new ApplicationImpersonationContext()) { state.InitInternal(context, this._state, this._eventHandlerMethods); } } ...... } 首先初始化Modules(InitModules) private void InitModules() { HttpModuleCollection modules = RuntimeConfig.GetAppConfig().HttpModules.CreateModules(); HttpModuleCollection other = this.CreateDynamicModules(); modules.AppendCollection(other); this._moduleCollection = modules; this.InitModulesCommon(); } 接下来完成事件的绑定(19个管道事件):BuildSteps: if (HttpRuntime.UseIntegratedPipeline) { this._stepManager = new PipelineStepManager(this); } else { this._stepManager = new ApplicationStepManager(this); } this._stepManager.BuildSteps(this._resumeStepsWaitCallback); } ...... BuildSteps完成HttpApplication19个管道事件的注册: internal override void BuildSteps(WaitCallback stepCallback) { ArrayList steps = new ArrayList(); HttpApplication app = base._application; bool flag = false; UrlMappingsSection urlMappings = RuntimeConfig.GetConfig().UrlMappings; flag = urlMappings.IsEnabled && (urlMappings.UrlMappings.Count > 0); steps.Add(new HttpApplication.ValidateRequestExecutionStep(app)); steps.Add(new HttpApplication.ValidatePathExecutionStep(app)); if (flag) { steps.Add(new HttpApplication.UrlMappingsExecutionStep(app)); } app.CreateEventExecutionSteps(HttpApplication.EventBeginRequest, steps); app.CreateEventExecutionSteps(HttpApplication.EventAuthenticateRequest, steps); app.CreateEventExecutionSteps(HttpApplication.EventDefaultAuthentication, steps); app.CreateEventExecutionSteps(HttpApplication.EventPostAuthenticateRequest, steps); app.CreateEventExecutionSteps(HttpApplication.EventAuthorizeRequest, steps); app.CreateEventExecutionSteps(HttpApplication.EventPostAuthorizeRequest, steps); app.CreateEventExecutionSteps(HttpApplication.EventResolveRequestCache, steps); app.CreateEventExecutionSteps(HttpApplication.EventPostResolveRequestCache, steps); steps.Add(new HttpApplication.MapHandlerExecutionStep(app));//----------------------> app.CreateEventExecutionSteps(HttpApplication.EventPostMapRequestHandler, steps); app.CreateEventExecutionSteps(HttpApplication.EventAcquireRequestState, steps); app.CreateEventExecutionSteps(HttpApplication.EventPostAcquireRequestState, steps); app.CreateEventExecutionSteps(HttpApplication.EventPreRequestHandlerExecute, steps); steps.Add(app.CreateImplicitAsyncPreloadExecutionStep()); steps.Add(newHttpApplication.CallHandlerExecutionStep(app));//---------------------->用于创建处理用户请求的对象(Handler) private void CreateEventExecutionSteps(object eventIndex, ArrayList steps) { AsyncAppEventHandler handler = this.AsyncEvents[eventIndex]; if (handler != null) { handler.CreateExecutionSteps(this, steps); } EventHandler handler2 = (EventHandler) this.Events[eventIndex]; if (handler2 != null) { Delegate[] invocationList = handler2.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { steps.Add(new SyncEventExecutionStep(this, (EventHandler) invocationList[i])); } } } 在HttpApplication对象初始化时,首先会调用InitModules方法来加载在web.config文件中配置的所有HttpModule模块。 接着HookupEventHandlersForApplicationAndModules方法被调用,这个方法完成global.asax文件中配置的HttpModule或HttpApplication事件的绑定 最后ApplicationStopManager对象的BuildSteps方法被调用,完成HttpApplication19个管道事件的注册。这个方法很重要,它将创建各种HttpApplication.IExecutionStep保存到一个数组列表: internal override void BuildSteps(WaitCallback stepCallback) { ..... this._execSteps = new HttpApplication.IExecutionStep[steps.Count]; steps.CopyTo(this._execSteps); ..... } 以便在BeginProcessRequest方法内部调用ResumeSteps方法依次执行这些对象的Execute()方法,完成各种处置。 调用BeginProcessRequest方法来实现IHttpAsyncHandler接口中定义的方法处理请求:IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) { this._context = context; this._context.ApplicationInstance = this; this._stepManager.InitRequest(); this._context.Root(); HttpAsyncResult result = new HttpAsyncResult(cb, extraData); this.AsyncResult = result; if (this._context.TraceIsEnabled) { HttpRuntime.Profile.StartRequest(this._context); } this.ResumeSteps(null);//---------->依次执行管道事件 return result; } BeginProcessRequest执行过程
void HttpApplication.IExecutionStep.Execute() { HttpContext context = this._application.Context; HttpRequest request = context.Request; if (EtwTrace.IsTraceEnabled(5, 1)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_ENTER, context.WorkerRequest); } context.Handler = this._application.MapHttpHandler(context, request.RequestType, request.FilePathObject, request.PhysicalPathInternal, false); if (EtwTrace.IsTraceEnabled(5, 1)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_LEAVE, context.WorkerRequest); } } 这儿调用了一个很重要的方法MapHttpHandler: context.Handler = this._application.MapHttpHandler(context, request.RequestType, request.FilePathObject, request.PhysicalPathInternal, false); internal IHttpHandler MapHttpHandler(HttpContext context, string requestType, VirtualPath path, string pathTranslated, bool useAppConfig) { IHttpHandler handler = (context.ServerExecuteDepth == 0) ? context.RemapHandlerInstance : null; ... IHttpHandlerFactory factory = this.GetFactory(mapping); try { IHttpHandlerFactory2 factory2 = factory as IHttpHandlerFactory2; if (factory2 != null) { handler = factory2.GetHandler(context, requestType, path, pathTranslated); } else { handler = factory.GetHandler(context, requestType, path.VirtualPathString, pathTranslated); } } ... .... } return handler; } 通过实现了IHttpHandlerFactory(PageHandlerFactory 或者 SimpleHandlerFactory等)创建了HttpHandler 因为steps.Add(new HttpApplication.MapHandlerExecutionStep(app))注册了Handler,所以会在第八个事件里通过反射创建了页面请求的对象(实现了IHttpHandler接口)。void HttpApplication.IExecutionStep.Execute() { HttpContext context = this._application.Context; IHttpHandler handler = context.Handler; ..... ... IHttpAsyncHandler handler2 = (IHttpAsyncHandler) handler; this._sync = false; this._handler = handler2; .... }然后再第11个和12个事件之间,会调用了第八个事件创建的页面对象的ProcessRequest方法,具体内容详看我下一篇文章:《ASP.NET那点不为人知的事(二)》
|
请发表评论