Asp.Net 详解IIS内部运行原理
2015-06-18 13:32
851 查看
本章节主要讲IIS和Asp.Net 管道内部如何处理客户端Http请求,会较多的以代码的形式讲述,让大家对HttpApplication、HttpHandler、HttpApplicationFactory、Page这几个在处理请求过程中扮演重要角色的对象有更深入的了解。
我们都知道,当用户在浏览器地址栏中输入网址时,该请求会被IIS服务器捕获,如果是请求的是静态页面则由IIS本身处理并直接返回客户端,如果是动态页(*.aspx),通过一序列的前期(这部分处理过程本文不详细讲解,可以参考其他文章)的处理来到.NET运行时,然后交给Aspnet_ispai.dll处理,处理完成后返回处理结果。请求和处理过程可以分为:HttpRuntime->HttpModule->HtppApplicationFactory->HttpApplication->HttpHandlerFactory->HttpHandler->HttpModule->将请求结果返回到客户端。
下面我们通过单步调式跟踪System.Web.Dll源码来分析各个过程中关键处理函数(关于如何单步调式.Net FrameWork 源码我将在后面的文章中给出)
(说明:部分代码只保留了关键代码)
1、首先进入管道运行时中的托管入口函数
IIS集成模式:
在IPipelineRuntime.cs类中请求通知函数:ProcessRequestNotification,并调用ProcessRequestNotificationHelper函数
2、在ProcessRequestNotificationHelper函数中调用运行时HttpRuntime中的ProcessRequestNotification函数
3、在ProcessRequestNotification中调用ProcessRequestNotificationPrivate
4、处理请求通知ProcessRequestNotificationPrivate函数中调用了HttpApplicatioinFactory的GetApplicationInstance()函数来获取HttpApplication实例对象,并调用BeginProcessRequestNotification处理请求
IIS经典模式:
在ISAPIRuntime.cs类中请求 ProcessRequest函数并调用HttpRuntime.ProcessReques方法
1、HttpRuntime处理请求入口函数
2、ProcessRequestNoDemand函数,调用ProcessRequestNow函数
3、ProcessRequestNow函数,调用ProcessRequestInternal
4、ProcessRequestInternal函数,调用HttpApplicatioinFactory的GetApplicationInstance()函数来获取HttpApplication实例对象
说明:以上4个步骤集成模式和经典模式分不同的函数执行,从下面开始两种模式调用相同的函数,只是在函数中针对不同的模式进行不同的处理
5、进入HttpApplicationFactory,调用GetNormalApplicationInstance函数
6、进入GetNormalApplicationInstance函数,调用InitInternal初始化HttpApplication内部对象
7、进入HttpApplication,调用InitInternal函数来初始化Application内部对象。初始化HttpModule和建立处理执行步骤
8、初始化HttpModule,包含系统默认的HttpModule和自定义的HttpModule
1)、系统默认的HttpModule:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config
2)、自定义的HttpModule在网站的Web.config中配置
经典模式:
3)、经典模式初始化:
4)、初始化各个HttpModule对象.
5)、初始化HttpModule,在Init函数中注册HttpApplication对象的事件,这里举了两个例子
OutputCacheModule.cs web.config中默认第一个HttpModule
SessionStateModule.cs web.config中默认第二个HttpModule,实现Session的系统HttpModule
集成模式初始化HttpModule代码我就不贴出来了,大家可以在源码中查看
9、建立处理步骤BuildSteps,将所有要执行的步骤载入到一个IExecutionStep[]集合中,待后面ResumeSteps调用
经典模式:调用ApplicationStepManager类中的BuildSteps函数
集成模式:调用PipelineStepManager类中的 BuildSteps函数
10、真正处理请求阶段, 调用ResumeSteps函数来执行处理步骤
经典模式:
返回到ProcessRequestInternal函数中执行BeginProcessRequest函数
ResumeSteps函数,调用ExecuteStepl函数来执行处理步骤
集成模式:
返回到ProcessRequestNotificationPrivate函数,执行BeginProcessRequestNotification
BeginProcessRequestNotification函数,调用ResumeSteps执行处理步骤
ResumeSteps
11、ExecuteStep执行BuildSteps中的各个步骤
这里贴出了两个很重要的步骤:获取HttpHandler(MaterializeHandlerExecutionStep)和执行HttpHandler(CallHandlerExecutionStep)
经典模式:
MapHandlerExecutionStep
MapHttpHandler获取处理请求的HttpHandler
集成模式:
MaterializeHandlerExecutionStep步骤
12、执行callhandlerexecutestep步骤,调用handler.ProcessRequest(context),如果HttpHandler类型为Page,则开始Page页生命周期
13、进入Page类的 ProcessRequest方法开始处理请求
14、进入ProcessRequest,调用ProcessRequestMain函数
15、进入ProcessRequestMain,开始Page页面主体处理过程
至此,整个IIS处理Asp.Net完整请求就结束了,列举了各个关键处理阶段的处理函数。当我们了解.net framework内部处理机制后能够使我们理解Asp.Net运行机制和本质,对开发人员来说这很重要,不能只停留在会用会写的阶段,而且要知道其内部原理。这样不仅可以帮助我们编写更高效的代码,同时可以学习并借鉴微软的面向对象的编程思想,受益颇多!
我们都知道,当用户在浏览器地址栏中输入网址时,该请求会被IIS服务器捕获,如果是请求的是静态页面则由IIS本身处理并直接返回客户端,如果是动态页(*.aspx),通过一序列的前期(这部分处理过程本文不详细讲解,可以参考其他文章)的处理来到.NET运行时,然后交给Aspnet_ispai.dll处理,处理完成后返回处理结果。请求和处理过程可以分为:HttpRuntime->HttpModule->HtppApplicationFactory->HttpApplication->HttpHandlerFactory->HttpHandler->HttpModule->将请求结果返回到客户端。
下面我们通过单步调式跟踪System.Web.Dll源码来分析各个过程中关键处理函数(关于如何单步调式.Net FrameWork 源码我将在后面的文章中给出)
(说明:部分代码只保留了关键代码)
1、首先进入管道运行时中的托管入口函数
IIS集成模式:
在IPipelineRuntime.cs类中请求通知函数:ProcessRequestNotification,并调用ProcessRequestNotificationHelper函数
internal static int ProcessRequestNotification( IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, int flags) { try { //调用ProcessRequestNotificationHelper return ProcessRequestNotificationHelper(rootedObjectsPointer, nativeRequestContext, moduleData, flags); } catch(Exception e) { ApplicationManager.RecordFatalException(e); throw; } }
2、在ProcessRequestNotificationHelper函数中调用运行时HttpRuntime中的ProcessRequestNotification函数
internal static int ProcessRequestNotificationHelper( IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, int flags) { IIS7WorkerRequest wr = null; HttpContext context = null; RequestNotificationStatus status = RequestNotificationStatus.Continue; RootedObjects root; bool workerRequestWasJustCreated = false; try { status = HttpRuntime.ProcessRequestNotification(wr, context);//调用ProcessRequestNotification函数 } finally { } return (int)status; }
3、在ProcessRequestNotification中调用ProcessRequestNotificationPrivate
4、处理请求通知ProcessRequestNotificationPrivate函数中调用了HttpApplicatioinFactory的GetApplicationInstance()函数来获取HttpApplication实例对象,并调用BeginProcessRequestNotification处理请求
private RequestNotificationStatus ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) { RequestNotificationStatus status = RequestNotificationStatus.Pending; try { IHttpHandler handler = null; if (context.NeedToInitializeApp()) { try { EnsureFirstRequestInit(context); } catch { } context.Response.InitResponseWriter(); handler = HttpApplicationFactory.GetApplicationInstance(context);//获取HttpApplication实例 if (handler == null) throw new HttpException(SR.GetString(SR.Unable_create_app_object)); if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, handler.GetType().FullName, "Start"); HttpApplication app = handler as HttpApplication; if (app != null) { // associate the context with an application instance app.AssignContext(context); } } wr.SynchronizeVariables(context); if (context.ApplicationInstance != null) { // 处理请求 IAsyncResult ar = context.ApplicationInstance.BeginProcessRequestNotification(context, _requestNotificationCompletionCallback); if (ar.CompletedSynchronously) { status = RequestNotificationStatus.Continue; } } else if (handler != null) { // HttpDebugHandler is processed here handler.ProcessRequest(context); status = RequestNotificationStatus.FinishRequest; } else { status = RequestNotificationStatus.Continue; } } catch (Exception e) { } return status; }
IIS经典模式:
在ISAPIRuntime.cs类中请求 ProcessRequest函数并调用HttpRuntime.ProcessReques方法
1、HttpRuntime处理请求入口函数
public static void ProcessRequest(HttpWorkerRequest wr) { if (wr == null) throw new ArgumentNullException("wr"); if (HttpRuntime.UseIntegratedPipeline) { throw new PlatformNotSupportedException(SR.GetString(SR.Method_Not_Supported_By_Iis_Integrated_Mode, "HttpRuntime.ProcessRequest")); } ProcessRequestNoDemand(wr);//调用ProcessRequestNoDemand函数 }
2、ProcessRequestNoDemand函数,调用ProcessRequestNow函数
internal static void ProcessRequestNoDemand(HttpWorkerRequest wr) { RequestQueue rq = _theRuntime._requestQueue; wr.UpdateInitialCounters(); if (rq != null) // could be null before first request wr = rq.GetRequestToExecute(wr); if (wr != null) { CalculateWaitTimeAndUpdatePerfCounter(wr); wr.ResetStartTime(); ProcessRequestNow(wr);调用ProcessRequestNow } }
3、ProcessRequestNow函数,调用ProcessRequestInternal
internal static void ProcessRequestNow(HttpWorkerRequest wr) { _theRuntime.ProcessRequestInternal(wr);//调用ProcessRequestInternal }
4、ProcessRequestInternal函数,调用HttpApplicatioinFactory的GetApplicationInstance()函数来获取HttpApplication实例对象
private void ProcessRequestInternal(HttpWorkerRequest wr) { // Count active requests Interlocked.Increment(ref _activeRequestCount); // Get application instance IHttpHandler app = HttpApplicationFactory.GetApplicationInstance(context);//获取HttpApplication对象 if (app == null) throw new HttpException(SR.GetString(SR.Unable_create_app_object)); if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, app.GetType().FullName, "Start"); if (app is IHttpAsyncHandler) { // asynchronous handler IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler)app; context.AsyncAppHandler = asyncHandler; //来到了真正处理请求步骤 asyncHandler.BeginProcessRequest(context, _handlerCompletionCallback, context); } else { // synchronous handler app.ProcessRequest(context); FinishRequest(context.WorkerRequest, context, null); } } catch (Exception e) { context.Response.InitResponseWriter(); FinishRequest(wr, context, e); } }
说明:以上4个步骤集成模式和经典模式分不同的函数执行,从下面开始两种模式调用相同的函数,只是在函数中针对不同的模式进行不同的处理
5、进入HttpApplicationFactory,调用GetNormalApplicationInstance函数
internal static IHttpHandler GetApplicationInstance(HttpContext context) { if (_customApplication != null) return _customApplication; if (context.Request.IsDebuggingRequest) return new HttpDebugHandler(); _theApplicationFactory.EnsureInited(); _theApplicationFactory.EnsureAppStartCalled(context); return _theApplicationFactory.GetNormalApplicationInstance(context);//返回HttpApplication实例 }
6、进入GetNormalApplicationInstance函数,调用InitInternal初始化HttpApplication内部对象
private HttpApplication GetNormalApplicationInstance(HttpContext context) { HttpApplication app = null; lock (_freeList) { if (_numFreeAppInstances > 0) { app = (HttpApplication)_freeList.Pop(); _numFreeAppInstances--; if (_numFreeAppInstances < _minFreeAppInstances) { _minFreeAppInstances = _numFreeAppInstances; } } } if (app == null) { // If ran out of instances, create a new one app = (HttpApplication)HttpRuntime.CreateNonPublicInstance(_theApplicationType); using (new ApplicationImpersonationContext()) { app.InitInternal(context, _state, _eventHandlerMethods);//初始化Application内部对象 } } if (AppSettings.UseTaskFriendlySynchronizationContext) { // When this HttpApplication instance is no longer in use, recycle it. app.ApplicationInstanceConsumersCounter = new CountdownTask(1); // representing required call to HttpApplication.ReleaseAppInstance app.ApplicationInstanceConsumersCounter.Task.ContinueWith((_, o) => RecycleApplicationInstance((HttpApplication)o), app, TaskContinuationOptions.ExecuteSynchronously); } return app; }
7、进入HttpApplication,调用InitInternal函数来初始化Application内部对象。初始化HttpModule和建立处理执行步骤
internal void InitInternal(HttpContext context, HttpApplicationState state, MethodInfo[] handlers) { Debug.Assert(context != null, "context != null"); // Remember state _state = state; PerfCounters.IncrementCounter(AppPerfCounter.PIPELINES); try { try { // Remember context for config lookups _initContext = context; _initContext.ApplicationInstance = this; // Set config path to be application path for the application initialization context.ConfigurationPath = context.Request.ApplicationPathObject; // keep HttpContext.Current working while running user code using (new DisposableHttpContextWrapper(context)) { // Build module list from config 根据IIS集成模式和经典模式初始化HttpMudule if (HttpRuntime.UseIntegratedPipeline) { //集成模式 Debug.Assert(_moduleConfigInfo != null, "_moduleConfigInfo != null"); Debug.Assert(_moduleConfigInfo.Count >= 0, "_moduleConfigInfo.Count >= 0"); try { context.HideRequestResponse = true; _hideRequestResponse = true; InitIntegratedModules();//集成模式初始化HttpModule } finally { context.HideRequestResponse = false; _hideRequestResponse = false; } } else { //经典模式 InitModules();//经典模式初始化HttpModule // this is used exclusively for integrated mode Debug.Assert(null == _moduleContainers, "null == _moduleContainers"); } // Hookup event handlers via reflection if (handlers != null) HookupEventHandlersForApplicationAndModules(handlers); // Initialization of the derived class _context = context; if (HttpRuntime.UseIntegratedPipeline && _context != null) { _context.HideRequestResponse = true; } _hideRequestResponse = true; try { Init(); } catch (Exception e) { RecordError(e); } } if (HttpRuntime.UseIntegratedPipeline && _context != null) { _context.HideRequestResponse = false; } _hideRequestResponse = false; _context = null; _resumeStepsWaitCallback= new WaitCallback(this.ResumeStepsWaitCallback); // Construct the execution steps array <span style="color:#FF0000;"><strong>if (HttpRuntime.UseIntegratedPipeline) {</strong></span> //集成模式 调用PipelineStepManager <span style="color:#FF0000;"><strong>_stepManager = new PipelineStepManager(this);</strong></span> } else { <span style="color:#FF0000;"><strong> _stepManager = new ApplicationStepManager(this);</strong></span> //经典模式 调用 ApplicationStepManager } <span style="color:#FF0000;"><strong>_stepManager.BuildSteps(_resumeStepsWaitCallback);</strong></span> //建立执行处理步骤 } finally { _initInternalCompleted = true; // Reset config path context.ConfigurationPath = null; // don't hold on to the context _initContext.ApplicationInstance = null; _initContext = null; } } catch { // Protect against exception filters throw; } }
8、初始化HttpModule,包含系统默认的HttpModule和自定义的HttpModule
1)、系统默认的HttpModule:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config
2)、自定义的HttpModule在网站的Web.config中配置
经典模式:
<system.web> <httpModules> <add name="mymodule" type="WebApplication2.myModule"/> </httpModules> </system.web>集成模式:
<system.webServer> <modules> <add name="mymodule" type="WebApplication2.myModule"/> </modules> </system.webServer>
3)、经典模式初始化:
private void InitModules() { //读取配置文件中HttpModules节点 HttpModulesSection pconfig = RuntimeConfig.GetAppConfig().HttpModules; //获取HttpModule集合 HttpModuleCollection moduleCollection = pconfig.CreateModules(); HttpModuleCollection dynamicModules = CreateDynamicModules(); moduleCollection.AppendCollection(dynamicModules); _moduleCollection = moduleCollection; // don't assign until all ops have succeeded InitModulesCommon();//调用InitModulesCommon }
4)、初始化各个HttpModule对象.
private void InitModulesCommon() { int n = _moduleCollection.Count; for (int i = 0; i < n; i++) { // remember the module being inited for event subscriptions // we'll later use this for routing _currentModuleCollectionKey = _moduleCollection.GetKey(i); _moduleCollection[i].Init(this);//初始化每个HttpModule } _currentModuleCollectionKey = null; InitAppLevelCulture(); }
5)、初始化HttpModule,在Init函数中注册HttpApplication对象的事件,这里举了两个例子
OutputCacheModule.cs web.config中默认第一个HttpModule
void IHttpModule.Init(HttpApplication app) { OutputCacheSection cacheConfig = RuntimeConfig.GetAppConfig().OutputCache; if (cacheConfig.EnableOutputCache) { app.ResolveRequestCache += new EventHandler(this.OnEnter); app.UpdateRequestCache += new EventHandler(this.OnLeave); } }
SessionStateModule.cs web.config中默认第二个HttpModule,实现Session的系统HttpModule
public void Init(HttpApplication app) { bool initModuleCalled = false; SessionStateSection config = RuntimeConfig.GetAppConfig().SessionState; if (!s_oneTimeInit) { s_lock.AcquireWriterLock(); try { if (!s_oneTimeInit) { InitModuleFromConfig(app, config); initModuleCalled = true; if (!CheckTrustLevel(config)) s_trustLevelInsufficient = true; s_timeout = (int)config.Timeout.TotalMinutes; s_useHostingIdentity = config.UseHostingIdentity; // See if we can try InProc optimization. See inline doc of s_allowInProcOptimization // for details. if (config.Mode == SessionStateMode.InProc && _usingAspnetSessionIdManager) { s_allowInProcOptimization = true; } if (config.Mode != SessionStateMode.Custom && config.Mode != SessionStateMode.Off && !config.RegenerateExpiredSessionId) { s_allowDelayedStateStoreItemCreation = true; } s_configExecutionTimeout = RuntimeConfig.GetConfig().HttpRuntime.ExecutionTimeout; s_configRegenerateExpiredSessionId = config.RegenerateExpiredSessionId; s_configCookieless = config.Cookieless; s_configMode = config.Mode; // The last thing to set in this if-block. s_oneTimeInit = true; Debug.Trace("SessionStateModuleInit", "Configuration: _mode=" + config.Mode + ";Timeout=" + config.Timeout + ";CookieMode=" + config.Cookieless + ";SqlConnectionString=" + config.SqlConnectionString + ";StateConnectionString=" + config.StateConnectionString + ";s_allowInProcOptimization=" + s_allowInProcOptimization + ";s_allowDelayedStateStoreItemCreation=" + s_allowDelayedStateStoreItemCreation); } } finally { s_lock.ReleaseWriterLock(); } } if (!initModuleCalled) { InitModuleFromConfig(app, config); } if (s_trustLevelInsufficient) { throw new HttpException(SR.GetString(SR.Session_state_need_higher_trust)); } }
集成模式初始化HttpModule代码我就不贴出来了,大家可以在源码中查看
9、建立处理步骤BuildSteps,将所有要执行的步骤载入到一个IExecutionStep[]集合中,待后面ResumeSteps调用
经典模式:调用ApplicationStepManager类中的BuildSteps函数
internal class ApplicationStepManager : StepManager { private IExecutionStep[] _execSteps; private WaitCallback _resumeStepsWaitCallback; private int _currentStepIndex; private int _numStepCalls; private int _numSyncStepCalls; private int _endRequestStepIndex; internal ApplicationStepManager(HttpApplication app): base(app) { } internal override void BuildSteps(WaitCallback stepCallback ) { ArrayList steps = new ArrayList(); HttpApplication app = _application; bool urlMappingsEnabled = false; UrlMappingsSection urlMappings = RuntimeConfig.GetConfig().UrlMappings; urlMappingsEnabled = urlMappings.IsEnabled && ( urlMappings.UrlMappings.Count > 0 ); steps.Add(new ValidateRequestExecutionStep(app)); steps.Add(new ValidatePathExecutionStep(app)); if (urlMappingsEnabled) steps.Add(new UrlMappingsExecutionStep(app)); // url mappings 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 MapHandlerExecutionStep(app));//分配一个Handler app.CreateEventExecutionSteps(HttpApplication.EventPostMapRequestHandler, steps); app.CreateEventExecutionSteps(HttpApplication.EventAcquireRequestState, steps); app.CreateEventExecutionSteps(HttpApplication.EventPostAcquireRequestState, steps); app.CreateEventExecutionSteps(HttpApplication.EventPreRequestHandlerExecute, steps); steps.Add(app.CreateImplicitAsyncPreloadExecutionStep()); // implict async preload step steps.Add(new CallHandlerExecutionStep(app)); // 执行HttpHandler app.CreateEventExecutionSteps(HttpApplication.EventPostRequestHandlerExecute, steps); app.CreateEventExecutionSteps(HttpApplication.EventReleaseRequestState, steps); app.CreateEventExecutionSteps(HttpApplication.EventPostReleaseRequestState, steps); steps.Add(new CallFilterExecutionStep(app)); // filtering app.CreateEventExecutionSteps(HttpApplication.EventUpdateRequestCache, steps); app.CreateEventExecutionSteps(HttpApplication.EventPostUpdateRequestCache, steps); _endRequestStepIndex = steps.Count; app.CreateEventExecutionSteps(HttpApplication.EventEndRequest, steps); steps.Add(new NoopExecutionStep()); // the last is always there _execSteps = new IExecutionStep[steps.Count]; steps.CopyTo(_execSteps); // callback for async completion when reposting to threadpool thread _resumeStepsWaitCallback = stepCallback; }
集成模式:调用PipelineStepManager类中的 BuildSteps函数
internal override void BuildSteps(WaitCallback stepCallback) { Debug.Trace("PipelineRuntime", "BuildSteps"); //ArrayList steps = new ArrayList(); HttpApplication app = _application; // add special steps that don't currently // correspond to a configured handler IExecutionStep materializeStep = new MaterializeHandlerExecutionStep(app); // implicit map step app.AddEventMapping( HttpApplication.IMPLICIT_HANDLER, RequestNotification.MapRequestHandler, false, materializeStep); // implicit async preload step app.AddEventMapping( HttpApplication.IMPLICIT_HANDLER, RequestNotification.ExecuteRequestHandler, false, app.CreateImplicitAsyncPreloadExecutionStep()); // implicit handler routing step IExecutionStep handlerStep = new CallHandlerExecutionStep(app); app.AddEventMapping( HttpApplication.IMPLICIT_HANDLER, RequestNotification.ExecuteRequestHandler, false, handlerStep); // implicit handler WebSockets step IExecutionStep webSocketsStep = new TransitionToWebSocketsExecutionStep(app); app.AddEventMapping( HttpApplication.IMPLICIT_HANDLER, RequestNotification.EndRequest, true /* isPostNotification */, webSocketsStep); // add implicit request filtering step IExecutionStep filterStep = new CallFilterExecutionStep(app); // normally, this executes during UpdateRequestCache as a high priority module app.AddEventMapping( HttpApplication.IMPLICIT_FILTER_MODULE, RequestNotification.UpdateRequestCache, false, filterStep); // for error conditions, this executes during LogRequest as a high priority module app.AddEventMapping( HttpApplication.IMPLICIT_FILTER_MODULE, RequestNotification.LogRequest, false, filterStep); _resumeStepsWaitCallback = stepCallback; }
10、真正处理请求阶段, 调用ResumeSteps函数来执行处理步骤
经典模式:
返回到ProcessRequestInternal函数中执行BeginProcessRequest函数
IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) { HttpAsyncResult result; // Setup the asynchronous stuff and application variables _context = context; _context.ApplicationInstance = this; _stepManager.InitRequest(); // Make sure the context stays rooted (including all async operations) _context.Root(); // Create the async result result = new HttpAsyncResult(cb, extraData); // Remember the async result for use in async completions AsyncResult = result; if (_context.TraceIsEnabled) HttpRuntime.Profile.StartRequest(_context); // Start the application ResumeSteps(null);//执行处理步骤 // Return the async result return result; }
ResumeSteps函数,调用ExecuteStepl函数来执行处理步骤
internal override void ResumeSteps(Exception error) { bool appCompleted = false; bool stepCompletedSynchronously = true; HttpApplication app = _application; CountdownTask appInstanceConsumersCounter = app.ApplicationInstanceConsumersCounter; HttpContext context = app.Context; ThreadContext threadContext = null; AspNetSynchronizationContextBase syncContext = context.SyncContext; Debug.Trace("Async", "HttpApplication.ResumeSteps"); try { if (appInstanceConsumersCounter != null) { appInstanceConsumersCounter.MarkOperationPending(); // ResumeSteps call started } using (syncContext.AcquireThreadLock()) { //执行步骤 error = app.ExecuteStep(_execSteps[_currentStepIndex], ref stepCompletedSynchronously); } }
集成模式:
返回到ProcessRequestNotificationPrivate函数,执行BeginProcessRequestNotification
BeginProcessRequestNotification函数,调用ResumeSteps执行处理步骤
internal IAsyncResult BeginProcessRequestNotification(HttpContext context, AsyncCallback cb) { if (this._context == null) { this.AssignContext(context); } context.CurrentModuleEventIndex = -1; HttpAsyncResult result = new HttpAsyncResult(cb, context); context.NotificationContext.AsyncResult = result; this.ResumeSteps(null);//开始执行处理步骤 return result; }
ResumeSteps
// PipelineStepManager::ResumeSteps // called from IIS7 (on IIS thread) via BeginProcessRequestNotification // or from an async completion (on CLR thread) via HttpApplication::ResumeStepsFromThreadPoolThread // This attribute prevents undesirable 'just-my-code' debugging behavior (VSWhidbey 404406/VSWhidbey 609188) [System.Diagnostics.DebuggerStepperBoundaryAttribute] internal override void ResumeSteps(Exception error) { HttpContext context = _application.Context; IIS7WorkerRequest wr = context.WorkerRequest as IIS7WorkerRequest; AspNetSynchronizationContextBase syncContext = context.SyncContext; RequestNotificationStatus status = RequestNotificationStatus.Continue; ThreadContext threadContext = null; bool needToDisassociateThreadContext = false; bool isSynchronousCompletion = false; bool needToComplete = false; bool stepCompletedSynchronously = false; int currentModuleLastEventIndex = _application.CurrentModuleContainer.GetEventCount(context.CurrentNotification, context.IsPostNotification) - 1; CountdownTask appInstanceConsumersCounter = _application.ApplicationInstanceConsumersCounter; using (context.RootedObjects.WithinTraceBlock()) { error = _application.ExecuteStep(step, ref stepCompletedSynchronously);//执行处理步骤 } }
11、ExecuteStep执行BuildSteps中的各个步骤
internal Exception ExecuteStep(IExecutionStep step, ref bool completedSynchronously) { Exception error = null; try { try { if (step.IsCancellable) { _context.BeginCancellablePeriod(); // request can be cancelled from this point try { step.Execute(); } finally { _context.EndCancellablePeriod(); // request can be cancelled until this point } _context.WaitForExceptionIfCancelled(); // wait outside of finally } else { step.Execute();</strong></span> } if (!step.CompletedSynchronously) { completedSynchronously = false; return null; } } }
这里贴出了两个很重要的步骤:获取HttpHandler(MaterializeHandlerExecutionStep)和执行HttpHandler(CallHandlerExecutionStep)
经典模式:
MapHandlerExecutionStep
// execution step -- map HTTP handler (used to be a separate module) internal class <span style="color:#FF0000;"><strong>MapHandlerExecutionStep </strong></span>: IExecutionStep { private HttpApplication _application; internal MapHandlerExecutionStep(HttpApplication app) { _application = app; } void IExecutionStep.Execute() { HttpContext context = _application.Context; HttpRequest request = context.Request; if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_ENTER, context.WorkerRequest); //获取HttpHandler context.Handler = _application.MapHttpHandler( context, request.RequestType, request.FilePathObject, request.PhysicalPathInternal, false /*useAppConfig*/);</strong></span> Debug.Assert(context.ConfigurationPath == context.Request.FilePathObject, "context.ConfigurationPath (" + context.ConfigurationPath + ") != context.Request.FilePath (" + context.Request.FilePath + ")"); if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_LEAVE, context.WorkerRequest); } bool IExecutionStep.CompletedSynchronously { get { return true;} } bool IExecutionStep.IsCancellable { get { return false; } } }
MapHttpHandler获取处理请求的HttpHandler
internal IHttpHandler MapHttpHandler(HttpContext context, string requestType, VirtualPath path, string pathTranslated, bool useAppConfig) { IHttpHandler handler = (context.ServerExecuteDepth == 0) ? context.RemapHandlerInstance : null; using (new ApplicationImpersonationContext()) { if (handler != null) { return handler; } HttpHandlerAction mapping = this.GetHandlerMapping(context, requestType, path, useAppConfig); if (mapping == null) { PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_NOT_FOUND); PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_FAILED); throw new HttpException(SR.GetString("Http_handler_not_found_for_request_type", new object[] { requestType })); } IHttpHandlerFactory factory = this.GetFactory(mapping);//获取HttpHandlerFactory对象,如果网站Web.config中自定义了HttpHandlerFactory对象,则会覆盖系统默认的 try { IHttpHandlerFactory2 factory2 = factory as IHttpHandlerFactory2; if (factory2 != null) { handler = factory2.GetHandler(context, requestType, path, pathTranslated);//获取HttpHandler对象,如果为自定义的HttpHandlerFactory,则返回自定义HttpHandlerFactory中设置的HttpHandler } else { handler = factory.GetHandler(context, requestType, path.VirtualPathString, pathTranslated); } } catch (FileNotFoundException exception) { if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) { throw new HttpException(0x194, null, exception); } throw new HttpException(0x194, null); } catch (DirectoryNotFoundException exception2) { if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) { throw new HttpException(0x194, null, exception2); } throw new HttpException(0x194, null); } catch (PathTooLongException exception3) { if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) { throw new HttpException(0x19e, null, exception3); } throw new HttpException(0x19e, null); } if (this._handlerRecycleList == null) { this._handlerRecycleList = new ArrayList(); } this._handlerRecycleList.Add(new HandlerWithFactory(handler, factory)); } return handler; }
集成模式:
MaterializeHandlerExecutionStep步骤
internal class MaterializeHandlerExecutionStep: IExecutionStep { private HttpApplication _application; internal MaterializeHandlerExecutionStep(HttpApplication app) { _application = app; } void IExecutionStep.Execute() { HttpContext context = _application.Context; HttpRequest request = context.Request; IHttpHandler handler = null; string configType = null; if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_ENTER, context.WorkerRequest); IIS7WorkerRequest wr = context.WorkerRequest as IIS7WorkerRequest; // Get handler if (context.RemapHandlerInstance != null){ //RemapHandler overrides all wr.SetScriptMapForRemapHandler(); context.Handler = context.RemapHandlerInstance; } else if (request.RewrittenUrl != null) { // RewritePath, we need to re-map the handler bool handlerExists; configType = wr.ReMapHandlerAndGetHandlerTypeString(context, request.Path, out handlerExists); if (!handlerExists) { // WOS 1973590: When RewritePath is used with missing handler in Integrated Mode,an empty response 200 is returned instead of 404 throw new HttpException(404, SR.GetString(SR.Http_handler_not_found_for_request_type, request.RequestType)); } } else { configType = wr.GetManagedHandlerType(); } if (!String.IsNullOrEmpty(configType)) { IHttpHandlerFactory factory = _application.GetFactory(configType);//获取HttpHandlerFactory对象 string pathTranslated = request.PhysicalPathInternal; try { handler = factory.GetHandler(context, request.RequestType, request.FilePath, pathTranslated);//获取HttpHandler对象 } catch (FileNotFoundException e) { if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) throw new HttpException(404, null, e); else throw new HttpException(404, null); } catch (DirectoryNotFoundException e) { if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) throw new HttpException(404, null, e); else throw new HttpException(404, null); } catch (PathTooLongException e) { if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) throw new HttpException(414, null, e); else throw new HttpException(414, null); } context.Handler = handler; // Remember for recycling if (_application._handlerRecycleList == null) _application._handlerRecycleList = new ArrayList(); _application._handlerRecycleList.Add(new HandlerWithFactory(handler, factory)); } if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_LEAVE, context.WorkerRequest); } bool IExecutionStep.CompletedSynchronously { get { return true;} } bool IExecutionStep.IsCancellable { get { return false; } } }
12、执行callhandlerexecutestep步骤,调用handler.ProcessRequest(context),如果HttpHandler类型为Page,则开始Page页生命周期
internal class CallHandlerExecutionStep: IExecutionStep { private HttpApplication _application; private AsyncCallback _completionCallback; private IHttpAsyncHandler _handler; // per call private AsyncStepCompletionInfo _asyncStepCompletionInfo; // per call private bool _sync; // per call internal CallHandlerExecutionStep(HttpApplication app) { _application = app; _completionCallback = new AsyncCallback(this.OnAsyncHandlerCompletion); } voidIExecutionStep.Execute() { HttpContext context = _application.Context; IHttpHandler handler = context.Handler; if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Information, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_ENTER, context.WorkerRequest); if (handler != null && HttpRuntime.UseIntegratedPipeline) { IIS7WorkerRequest wr = context.WorkerRequest as IIS7WorkerRequest; if (wr != null && wr.IsHandlerExecutionDenied()) { _sync = true; HttpException error = new HttpException(403, SR.GetString(SR.Handler_access_denied)); error.SetFormatter(new PageForbiddenErrorFormatter(context.Request.Path, SR.GetString(SR.Handler_access_denied))); throw error; } } if (handler == null) { _sync = true; } else if (handler is IHttpAsyncHandler) { // asynchronous handler IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler)handler; _sync = false; _handler = asyncHandler; var beginProcessRequestDelegate = AppVerifier.WrapBeginMethod<HttpContext>(_application, asyncHandler.BeginProcessRequest); _asyncStepCompletionInfo.Reset(); context.SyncContext.AllowVoidAsyncOperations(); IAsyncResult ar; try { ar = beginProcessRequestDelegate(context, _completionCallback, null); } catch { // The asynchronous step has completed, so we should disallow further // async operations until the next step. context.SyncContext.ProhibitVoidAsyncOperations(); throw; } bool operationCompleted; bool mustCallEndHandler; _asyncStepCompletionInfo.RegisterBeginUnwound(ar, out operationCompleted, out mustCallEndHandler); if (operationCompleted) { _sync = true; _handler = null; // not to remember // The asynchronous step has completed, so we should disallow further // async operations until the next step. context.SyncContext.ProhibitVoidAsyncOperations(); try { if (mustCallEndHandler) { asyncHandler.EndProcessRequest(ar); } _asyncStepCompletionInfo.ReportError(); } finally { SuppressPostEndRequestIfNecessary(context); // In Integrated mode, generate the necessary response headers // after the ASP.NET handler runs context.Response.GenerateResponseHeadersForHandler(); } if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Information, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LEAVE, context.WorkerRequest); } } else { //同步 handler _sync = true; context.SyncContext.SetSyncCaller(); try { handler.ProcessRequest(context);//开始Page页面生命周期 } finally { context.SyncContext.ResetSyncCaller(); if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Information, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LEAVE, context.WorkerRequest); SuppressPostEndRequestIfNecessary(context); context.Response.GenerateResponseHeadersForHandler(); } } } bool IExecutionStep.CompletedSynchronously { get { return _sync;} } bool IExecutionStep.IsCancellable { // launching of async handler should not be cancellable get { return (_application.Context.Handler is IHttpAsyncHandler) ? false : true; } } }
13、进入Page类的 ProcessRequest方法开始处理请求
private void ProcessRequest() { // culture needs to be saved/restored only on synchronous pages (if at all) // save culture Thread currentThread = Thread.CurrentThread; CultureInfo prevCulture = currentThread.CurrentCulture; CultureInfo prevUICulture = currentThread.CurrentUICulture; try { ProcessRequest(true /*includeStagesBeforeAsyncPoint*/, true /*includeStagesAfterAsyncPoint*/);//调用ProcessRequest函数 } finally { // restore culture RestoreCultures(currentThread, prevCulture, prevUICulture); } }
14、进入ProcessRequest,调用ProcessRequestMain函数
private void ProcessRequest(bool includeStagesBeforeAsyncPoint, bool includeStagesAfterAsyncPoint) { // Initialize the object and build the tree of controls. // This must happen *after* the intrinsics have been set. // On async pages only call Initialize once (ProcessRequest is called twice) if (includeStagesBeforeAsyncPoint) { FrameworkInitialize(); this.ControlState = ControlState.FrameworkInitialized; } bool needToCallEndTrace = Context.WorkerRequest is IIS7WorkerRequest; try { try { if (IsTransacted) { ProcessRequestTransacted(); } else { // No transactions ProcessRequestMain(includeStagesBeforeAsyncPoint, includeStagesAfterAsyncPoint);//调用ProcessRequestMain函数 } if (includeStagesAfterAsyncPoint) { needToCallEndTrace = false; ProcessRequestEndTrace(); } } catch (ThreadAbortException) { try { if (needToCallEndTrace) ProcessRequestEndTrace(); } catch {} } finally { if (includeStagesAfterAsyncPoint) { ProcessRequestCleanup(); } } } catch { throw; } // Prevent Exception Filter Security Issue (ASURT 122835) }
15、进入ProcessRequestMain,开始Page页面主体处理过程
private void ProcessRequestMain(bool includeStagesBeforeAsyncPoint, bool includeStagesAfterAsyncPoint) { try { HttpContext con = Context; string exportedWebPartID = null; if (con.TraceIsEnabled) Trace.Write("aspx.page", "Begin PreInit"); if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_PRE_INIT_ENTER, _context.WorkerRequest); PerformPreInit(); //Page页面生命周期的OnPerLoad阶段 if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_PRE_INIT_LEAVE, _context.WorkerRequest); if (con.TraceIsEnabled) Trace.Write("aspx.page", "End PreInit"); if (con.TraceIsEnabled) Trace.Write("aspx.page", "Begin Init"); if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_INIT_ENTER, _context.WorkerRequest); InitRecursive(null); if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_INIT_LEAVE, _context.WorkerRequest); if (con.TraceIsEnabled) Trace.Write("aspx.page", "End Init"); if (con.TraceIsEnabled) Trace.Write("aspx.page", "Begin InitComplete"); OnInitComplete(EventArgs.Empty);//Page页面生命周期的OnInitComplete阶段 if (con.TraceIsEnabled) Trace.Write("aspx.page", "End InitComplete"); if (IsPostBack) { if (con.TraceIsEnabled) Trace.Write("aspx.page", "Begin LoadState"); if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_LOAD_VIEWSTATE_ENTER, _context.WorkerRequest); LoadAllState();//Page页面生命周期的LoadViewState阶段(加载视图状态) if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_LOAD_VIEWSTATE_LEAVE, _context.WorkerRequest); if (con.TraceIsEnabled) { Trace.Write("aspx.page", "End LoadState"); Trace.Write("aspx.page", "Begin ProcessPostData"); } if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_LOAD_POSTDATA_ENTER, _context.WorkerRequest); ProcessPostData(_requestValueCollection, true /* fBeforeLoad */);//Page页面生命周期ProcessPostData阶段(处理回发数据) if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_LOAD_POSTDATA_LEAVE, _context.WorkerRequest); if (con.TraceIsEnabled) Trace.Write("aspx.page", "End ProcessPostData"); } if (con.TraceIsEnabled) Trace.Write("aspx.page", "Begin PreLoad"); OnPreLoad(EventArgs.Empty);//Page页面生命周期OnPreLoad阶段(预加载) if (con.TraceIsEnabled) Trace.Write("aspx.page", "End PreLoad"); if (con.TraceIsEnabled) Trace.Write("aspx.page", "Begin Load"); if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_LOAD_ENTER, _context.WorkerRequest); LoadRecursive();//Page页面生命周期Load阶段(加载) if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_LOAD_LEAVE, _context.WorkerRequest); if (con.TraceIsEnabled) Trace.Write("aspx.page", "End Load"); if (IsPostBack) { // Try process the post data again (ASURT 29045) if (con.TraceIsEnabled) Trace.Write("aspx.page", "Begin ProcessPostData Second Try"); <span style="color:#FF0000;"><strong> ProcessPostData(_leftoverPostData, false /* !fBeforeLoad */);//Page页面生命周期 ProcessPostData阶段</strong></span> if (con.TraceIsEnabled) { Trace.Write("aspx.page", "End ProcessPostData Second Try"); Trace.Write("aspx.page", "Begin Raise ChangedEvents"); } if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_POST_DATA_CHANGED_ENTER, _context.WorkerRequest); RaiseChangedEvents();//Page页面生命周期 RaiseChangedEvents阶段(处理回发更改事件) if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_POST_DATA_CHANGED_LEAVE, _context.WorkerRequest); if (con.TraceIsEnabled) { Trace.Write("aspx.page", "End Raise ChangedEvents"); Trace.Write("aspx.page", "Begin Raise PostBackEvent"); } if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_RAISE_POSTBACK_ENTER, _context.WorkerRequest); RaisePostBackEvent(_requestValueCollection);//Page页面生命周期 RaisePostBackEvent阶段(处理回发事件) if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_RAISE_POSTBACK_LEAVE, _context.WorkerRequest); if (con.TraceIsEnabled) Trace.Write("aspx.page", "End Raise PostBackEvent"); } if (con.TraceIsEnabled) Trace.Write("aspx.page", "Begin LoadComplete"); OnLoadComplete(EventArgs.Empty);//Page页面生命周期 加载完成 if (con.TraceIsEnabled) Trace.Write("aspx.page", "End LoadComplete"); if (IsPostBack && IsCallback) { PrepareCallback(callbackControlId);//Page页面生命周期 PrepareRender(预呈现) } else if (!IsCrossPagePostBack) { if (con.TraceIsEnabled) Trace.Write("aspx.page", "Begin PreRender"); if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_PRE_RENDER_ENTER, _context.WorkerRequest); PreRenderRecursiveInternal(); if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_PRE_RENDER_LEAVE, _context.WorkerRequest); if (con.TraceIsEnabled) Trace.Write("aspx.page", "End PreRender"); } } /// Async Point here if (_legacyAsyncInfo == null || _legacyAsyncInfo.CallerIsBlocking) { // for non-async pages with registered async tasks - run the tasks here // also when running async page via server.execute - run the tasks here ExecuteRegisteredAsyncTasks(); } // Make sure RawUrl gets validated. ValidateRawUrlIfRequired(); if (includeStagesAfterAsyncPoint) { if (IsCallback) { RenderCallback(); return; } if (IsCrossPagePostBack) { return; } if (con.TraceIsEnabled) Trace.Write("aspx.page", "Begin PreRenderComplete"); PerformPreRenderComplete(); if (con.TraceIsEnabled) Trace.Write("aspx.page", "End PreRenderComplete"); if (con.TraceIsEnabled) { BuildPageProfileTree(EnableViewState); Trace.Write("aspx.page", "Begin SaveState"); } if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_SAVE_VIEWSTATE_ENTER, _context.WorkerRequest); SaveAllState();//Page页面生命周期 SaveAllState阶段(保存视图状态) if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_SAVE_VIEWSTATE_LEAVE, _context.WorkerRequest); if (con.TraceIsEnabled) { Trace.Write("aspx.page", "End SaveState"); Trace.Write("aspx.page", "Begin SaveStateComplete"); } OnSaveStateComplete(EventArgs.Empty); if (con.TraceIsEnabled) { Trace.Write("aspx.page", "End SaveStateComplete"); Trace.Write("aspx.page", "Begin Render"); } if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_RENDER_ENTER, _context.WorkerRequest); // Special-case Web Part Export so it executes in the same security context as the page itself (VSWhidbey 426574) if (exportedWebPartID != null) { ExportWebPart(exportedWebPartID); } else { RenderControl(CreateHtmlTextWriter(Response.Output));//Page页面生命周期 Render阶段(呈现) } if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_RENDER_LEAVE, _context.WorkerRequest); if (con.TraceIsEnabled) Trace.Write("aspx.page", "End Render"); CheckRemainingAsyncTasks(false); } }
至此,整个IIS处理Asp.Net完整请求就结束了,列举了各个关键处理阶段的处理函数。当我们了解.net framework内部处理机制后能够使我们理解Asp.Net运行机制和本质,对开发人员来说这很重要,不能只停留在会用会写的阶段,而且要知道其内部原理。这样不仅可以帮助我们编写更高效的代码,同时可以学习并借鉴微软的面向对象的编程思想,受益颇多!
相关文章推荐
- .NET跨平台:在Ubuntu上用自己编译的dnx运行ASP.NET 5示例程序
- asp.net AspNetpager的用法
- ASP.NET MVC几种ActionResult的本质:FileResult
- C# WPF ASP.net 上传多文件和数据
- 由asp的一个错误,看语言的不同:asp & java
- asp 调用 vb(activex dll) ,参数传递(传引用)需要注意
- asp <----> vb(com,dll) <---> c 来回的调用,生命在于折腾
- asp 读cookie 下划线 丢失
- ASP 运行结果显示空白 --- 是编码的原因。
- 在ASP.NET 5项目中使用和调试外部源代码包
- ASP.NET如何定时执行任务
- Asp.net MVC添加移动支持
- ListView 使用方法(Asp.Net)
- 【asp.net】验证控件
- Asp.net安全架构之2:Session hijacking(会话劫持)
- aspx里构造函数里无法使用session,需要重写一个方法放在load里面就能正常使用session了
- ASP.NET Web API 创建帮助页
- AspNetPager控件的用法
- IIS6.0下 Asp.Net 拦截jpg请求
- aspx写cs后台代码(突破上传过滤一招,利用ashx)