8.2 ASP.NET pipeline and application life cycle
Section 8.1 introduces the system architecture of IIS and the overall process of HTTP request processing. From it, we can know that each ASP.NET website corresponds to a Web application, which can respond to HTTP requests and provide users with the required information. So, how exactly does an ASP.NET application respond to HTTP requests? What specific processing procedures are included? This involves the life cycle of ASP.NET applications.
8.2.1 ASP.NET application life cycle*
This section takes IIS 6 as an example to introduce step by step the process of processing HTTP requests by ASP.NET applications. The process of IIS 7 has some minor changes compared to IIS 6, but is generally consistent.
1 The browser issues an HTTP request to access an ASP.NET web page.
Assume that this request is the first request to the ASP.NET application to which this web page belongs.
When this request reaches the Web server, HTTP.SYS is responsible for receiving it. According to the URL of this request, HTTP.SYS passes it to the application pool corresponding to this ASP.NET application, and the application pool running in this application pool Worker processes are responsible for processing requests[1].
After the worker process receives this request, it loads an ISAPI extension "aspnet_isapi.dll" dedicated to processing ASP.NET pages and passes the HTTP request to it.
After the worker process loads aspnet_isapi.dll, aspnet_isapi.dll is responsible for loading the running environment of the ASP.NET application - CLR [2].
The worker process works in an unmanaged environment (referring to the Windows operating system itself), while the objects in .NET work in a managed environment (referring to the CLR). aspnet_isapi.dll acts as a bridge to communicate between the two. HTTP requests received (from an unmanaged environment) are forwarded to the corresponding .NET object (in a managed environment) for processing.
2 Create the ApplicationManager object and application domain
After the CLR is loaded, the ApplicationManager class is responsible for creating an application domain. Each ASP.NET application runs in its own application domain and is identified by a unique application identifier.
Each application domain corresponds to an instance of the ApplicationManager class, which is responsible for managing ASP.NET applications running in the domain (such as starting and stopping an ASP.NET application, in a specified ASP.NET application Create objects, etc.).
3 Create HostingEnvironment object
When creating an application domain for an ASP.NET application, a HostingEnvironment object is created, which provides some management information for the ASP.NET application (such as the identity of the ASP.NET application, the corresponding virtual directory and physical directory ), and provides some additional functionality (such as registering an object in the application domain, impersonating a specific user, etc.).
4 Create ASP.NET Core objects for each request
When the application domain is created, an ISAPIRuntime object is created and its ProcessRequest() method is automatically called. In this method, the ISAPIRuntime object creates an HttpWorkerRequest object based on the incoming HTTP request. This object wraps various information of the HTTP request in an object-oriented manner (that is, the original HTTP request information is encapsulated as an HttpWorkerRequest object). Then, call the StartProcessing() method of the ISAPIRuntime object to start the entire HTTP request processing process (this is the "HTTP Pipeline: HTTP Pipeline"). At the beginning of this processing process, an HttpRuntime type object is created, and the previously created HttpWorkerRequest object is used as The method parameters are passed to the ProcessRequest() method of this HttpRuntime object.
Some very important work is done in the ProcessRequest() method of the HttpRuntime class, among which the ones most closely related to Web software engineers are:
The ProcessRequest() method of the HttpRuntime class creates an HttpContext object based on the HTTP request information provided in the HttpWorkerRequest object.
The HttpContext object is important because this object contains two other objects that are very common in ASP.NET programming: HttpResponse and HttpRequest.
The information in the HttpRequest object comes from the original HTTP request. For example, its Url attribute represents the URL in the original HTTP request information.
The HttpResponse object has some properties and methods for generating information to be returned to the browser.
The Page class provides corresponding properties to reference these two objects, so you can directly use the "Requset" and "Response" properties to access these two objects in the ASP.NET web page. For example:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response .Write(Request .Url);
}
}
The Context property of the Page class refers to the HttpContext object, so the above code can also be rewritten in the following form:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.Context.Response .Write(this.Context.Request .Url);
}
}
Regarding the three objects HttpContext, HttpResponse and HttpRequest, you must master the following points:
l The HttpContext object contains two objects, HttpResponse and HttpRequest. You can obtain HTTP request-related information from the HttpRequest object, and the content to be output to the browser can be achieved by calling the HttpResponse method.
l For each HTTP request, ASP.NET creates an HttpContext object, which is accessible during the entire HTTP processing.
5 Allocate an HttpApplication object to handle the request
In addition to creating the HttpContext object, the ProcessRequest() method of the HttpRuntime class also completes another very important job - applying to allocate an HttpApplication object to an instance of the HttpApplicationFactory class [3] to manage each step in the entire HTTP request processing pipeline. kind of event.
The HttpApplicationFactory object is responsible for managing an HttpApplication object pool [4]. When an HTTP request comes, if there is an available HttpApplication object in the pool, this object is directly allocated to process the HTTP request. Otherwise, a new HttpApplication object is created.
6 The HttpApplication object starts the HTTP pipeline
The HttpApplication object is responsible for assembling the entire "HTTP request processing pipeline (HTTP Pipeline)". The "HTTP request processing pipeline" can be compared to the "production pipeline" in a modern factory. The HttpContext object created in the previous step is the "product" to be processed by this production pipeline. When it flows through different parts of the "production pipeline", it will be processed and processed specifically.
How do these specific “processes and treatments” take place?
Simply put, when the HttpContext object passes through different parts of the "production pipeline", the HttpApplication object will trigger a series of events [5]. A specific component - the HTTP module (HTTP Module) can respond to these events. In this event response code, the HttpContext object can be "processed and processed". In this sense, the HTTP module can be regarded as a "production pipeline" ” workers in. The HTTP module is actually the "ISAPI filter" introduced earlier.
The HTTP module object is created in the InitModules() method [6] of the HttpApplication object. We generally write code in the Init() method [7] of the HTTP module object so that it can respond to specific events triggered by the HttpApplication object.
ASP.NET provides some predefined HTTP modules to respond to specific events, and Web software engineers can also write their own HTTP modules and insert them into the "HTTP request processing pipeline" [8].
In the middle of the pipeline (after processing related events), the HttpContext object is received by the final Page object (this is why the HttpContext object can be accessed in the ASP.NET page through the Context property defined by the Page class).
Each accessed ASP.NET page will be converted into a "page class derived from the Page class".
Note: The Page class implements the IHttpHandler interface, which defines a ProcessRequest() method.
After the ASP.NET page class is generated, it is automatically compiled into an assembly, and then its ProcessRequest() method is automatically called (because the Page class implements the IHttpHandler interface, it must have this method). In this method, the code written by the web software engineer is executed (if any). The execution result of the ProcessRequest() method is once again carried by the HttpContext object, control is transferred back to the "HTTP request processing pipeline", and the HttpApplication object continues to fire subsequent events. At this time, if there are specific HTTP modules that respond to these events, they will be automatically called.
The HttpContext object brings the final processing result to the end of the "HTTP request processing pipeline", and its information is taken out and transmitted to the worker process again using aspnet_isapi.dll as a bridge. The worker process then transfers the processing results of the HTTP request to HTTP.SYS, which is responsible for returning the results to the browser.
According to the previous introduction, the entire HTTP pipeline can be divided into three sections: preprocessing stage à processing stage à post-processing stage (Figure 8 ‑14).
Figure 8 ‑ 14 Three stages of HTTP pipeline
As shown in Figure 8 ‑14, the pre-processing and post-processing stages of the HTTP pipeline are mainly participated by multiple HTTP modules and are driven by events. The work completed in these two stages is mainly to perform various attributes of the HttpContext object. Revise.
The processing of HTTP requests is ultimately completed in the "processing phase" by an object that implements the IHttpHandler interface. Every page class generated by ASP.NET web pages implements this interface. The PageHandlerFactory object [9] is responsible for creating a suitable HTTP request processing object.
It can be seen that the object that implements the IHttpHandler interface is responsible for processing HTTP requests, which is why it is called "Handler (handler)".
In addition to the most common ASP.NET web pages, Web software engineers can also create their own objects that implement the IHttpHandler interface and insert them into the HTTP pipeline to handle HTTP requests.
When the HTTP request is processed, the related objects are released, but the created application domain, HttpApplication and other objects still survive to respond to the next HTTP request.
7 ASP.NET application life cycle summary
This section introduces the life cycle of ASP.NET applications. This is a quite complex process. It may be easier to understand with the following popular analogy:
l "HTTP request processing pipeline" is a "production assembly line" in a modern factory, and the HttpContext object is the product to be processed on this assembly line.
l The HttpHandler (HTTP handler) object is the core of the entire "product production line", which is responsible for assembling the product into shape.
l HttpModule (HTTP module) is equivalent to auxiliary workers on the "production line". They perform "pre-processing" (preparing for product assembly) and "post-processing" (preparing for product delivery, such as labeling) on the product (HttpContext object) ).
l The HttpApplication object is the "leader" of the entire "production line". He is responsible for allocating workers to the "production line" (initializing and loading all registered HttpModules), and then triggering a series of events (called "ASP.NET application events" "), a specific HttpModule is responsible for responding to specific events.
-------------------------------------------------- ----------------------------------
[1] If the worker process does not exist, the IIS monitoring program WAS will create one, otherwise, the existing worker process will be reused.
[2] In IIS 7 integrated mode, since the CLR is preloaded, this step is not needed.
[3] "Instance of class" and "object of class" have the same meaning, and they both refer to objects created using classes as templates.
[4] Object pool (object pool) is a common object organization method in object-oriented software systems. It can be regarded as an object container. The object pool contains multiple objects created in advance. When the outside world needs an object, it can directly take out a ready-made object from the pool and use it, thus avoiding the performance loss caused by frequent object creation.
[5] HttpApplication defines quite a few events. For a complete list of events, please view MSDN.
[6] This method will be automatically called when obtaining the HttpApplication object.
[7] All HTTP modules must implement the IHttpModule interface, and the Init() method is defined by this interface.
[8] Customized HTTP modules can be added to the HTTP request processing flow by inserting specific content in Web.Config.
[9] This is another core in the ASP.NET technology framework