ASP. NET (8): httpmodule and httpapplication

Source: Internet
Author: User
Tags reflector

In the previous three sections, we talked about the construction, presentation, and Data Binding of controls. I think it's almost time. I wanted to talk about a custom control to end the control, but I personally don't like the control, so I am too lazy to write related content. Sorry. Although I do not like to use controls, I still like the design of the entire webform. One word: "amazing ". In the previous chapter, when we talked about the page lifecycle, some friends commented that there was too little content. From today on, let's talk about the lifecycle.

What is ihttpmodule? What is the use of web development?

First, we can see from the name that it is an interface, which is inherited by people. We have to inherit it and implement its method. Module refers to modules and components. If we have implemented this interface and configured the web. config to let IIS know that our web program uses this component. Is our program more than the default web program ?! Obviously, the methods defined in our components will be called when necessary, which is the use of httpmodule. To put it bluntly, we write an extension for IIS, but this extension is only for web programs that use (configure config. In fact, every web application is an IIS process, and the configuration file of this process is Web. config.

After understanding his meaning, we can start! Create a web application, create a class, inherit ihttpmodule, and implement its method. In the modules node of config, <Add name = "" type = ""/>, OK!

namespace WebApplication1 {     public class MyHttpModule : IHttpModule     {         public void Dispose()         {         }        public void Init(HttpApplication context)         {             context.Context.Response.Write(1);         }     } }
<? XML version = "1.0"?> <Configuration> <system. web> <compilation DEBUG = "true" targetframework = "4.0"/> 

There are two web. config configurations. The above one is for non-iis7, and the following is obviously for iis7. Start the program, what happend ?! Is there an additional 1 in the header of the page !! When we open any page, there will be a 1, indicating that our module has played a role, and that every request will execute the init method of httpmodule? Right?

Let's change the code:

 

       public void Init(HttpApplication context)         {             context.Context.Response.Write(1);             context.BeginRequest += OnBeginRequest;         }        public void OnBeginRequest(object sender, EventArgs e)         {             var app = (HttpApplication)sender;             var url = app.Context.Request.RawUrl;             app.Context.Response.Write(url);         }

Add a breakpoint to the init and onbeginrequest methods, re-compile them, and then F5 will look at it. Init only takes 1 time, while onbeginrequest does. The values of ur are default. aspx style.css and favorite. ICO; we can see that any URL request, including static files, will be executed by the event method we defined! It seems that this is much slower than processing only aspx!

The init operation must be performed once. Otherwise, the event will not be subscribed three times ?, But why does it take only one time? Why? Haha, it is actually very simple. The myhttpmodule will be instantiated once. after instantiation, execute init initialization and then it will reside in the application pool until the application pool is recycled, or he is crashed for various reasons, while onbeginrequest is subscribed to by the beginrequest event of the httpapplication class. What is event subscription? An event is a Special Delegate. What is delegation? A delegate is a method pointer. Therefore, as long as the delegate is executed, it will execute the method body to which it points, that is, onbeginrequest. It can be seen that the onbeginrequest execution is related to the beginrequest of httpapplication, it has nothing to do with myhttpmodule itself.

After three requests, it indicates that all three requests have executed beginrequest. Is each request instantiated an httpapplication? I can see from the name that no, because application (Application) Well, we currently run one, how can we continuously instantiate it! If you want to solve the root problem and thoroughly understand it, you have to go through the framework source code and debug it!

(------------ Declaration, the following source code can be skipped without full understanding, as long as you know that it is related to the request ------------)

Next we will investigate the initialization process of httpapplication!

Use reflector to check the classes in the system. Web namespace. You can see the httpapplicationfactory class, which is responsible for creating the httpapplication. When we started the site, it was slow for the first time. Why? Because of the initialization build work.

System. web. there are a bunch of build classes under the complilation namespace, including building global. asax, that is, our httpapplication class, is then cached into the factory stack and pop out when we need it. (You may have doubts, isn't pop gone? In fact, the app will push back during execution. For details, see httpapplication. releaseappinstance method)

Httpapplicationfactory has a getapplicationinstance method, which is used to obtain httpapplication:

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);} private httpapplication getnormalapplicationinstance (httpcontext context) {httpapplication application = NULL; lock (this. _ freelist) {If (this. _ numfreeappinstances> 0) {application = (httpapplication) This. _ freelist. pop (); // If _ freelist exists, it is obtained directly. This is not available only when this is built for the first time. _ numfreeappinstances --; If (this. _ numfreeappinstances <this. _ minfreeappinstances) {This. _ minfreeappinstances = This. _ numfreeappinstances ;}}if (Application = NULL) {application = (httpapplication) httpruntime. createnonpublicinstance (this. _ theapplicationtype); Using (New applicationimpersonationcontext () {application. initinternal (context, this. _ state, this. _ eventhandlermethods); // The application is initialized here, and will be pushed to _ freelist after complicated code.} return application ;}

Tracking this method, we can conclude that the application is cached, not always instantiated.

Through reflector's analysis, we can find that the getapplicationinstance method was called by httpruntime. processrequestnow and finally returned to our request.

Private void processrequestnow (httpworkerrequest wr) {httpcontext context; try {context = new httpcontext (WR, false); // instantiate context} catch {Wr. sendstatus (400, "Bad request"); Wr. sendknownresponseheader (12, "text/html; charset = UTF-8"); byte [] bytes = encoding. ASCII. getbytes ("<HTML> <body> bad request </body> 

The code above shows us the execution process of a request. This method is used for each request! Httpruntime has a requestqueue (Request queue), which executes all requests in sequence. Finally, I know why I used the application three times. If you are interested, you can track requestqueue again and I will not post it.

In addition, httpapplication means that it is the boss of the entire site. The myhttpmodule we define is only one of its many modules. You can also define multiple modules. add multiple modules in config.

During application initialization, there is a section for initializing the module. I will post it for you to see:

private void InitModules() {     this._moduleCollection = RuntimeConfig.GetAppConfig().HttpModules.CreateModules();     this.InitModulesCommon(); } 

Createmodules instantiates the configured module from the module node of Web. config.

internal HttpModuleCollection CreateModules() {     HttpModuleCollection modules = new HttpModuleCollection();     foreach (HttpModuleAction action in this.Modules)     {         modules.AddModule(action.Entry.ModuleName, action.Entry.Create());     }     modules.AddModule("DefaultAuthentication", new DefaultAuthenticationModule());     return modules; } 

Finally, Initialize all modules, including some modules of the system.

Private void initmodulescommon () {int COUNT = This. _ modulecollection. count; For (INT I = 0; I <count; I ++) {This. _ currentmodulecollectionkey = This. _ modulecollection. getkey (I); this. _ modulecollection [I]. init (this); // initialize each httpmodule} This. _ currentmodulecollectionkey = NULL; this. initapplevelculture ();}


(-------------- Jump here ----------------)

The httpapplication class exposes many events. The above sample program uses beginrequest, which is the first event to start execution. Its role is clear, that is, what do we need to prepare when the request starts execution? You may need urlrewriter :). The "event advertisement" is inserted below, and the advertisement will fly soon.

The above is just a simple example of "event is a Special Delegate", and I didn't elaborate on why it is special. I wonder if you understand the meaning of the incident? What is the significance of an event?

That's what I understand. "Event" represents the occurrence of one thing. For example, I design my daily life into a class. So what does one day's life contain? It includes many things to be done from morning till night, and even some fixed things.

The three details are as follows:

From the beginning to the end, it means that this is a process from the beginning to the end. Many things need to be done, which means that many things need to be executed in this process. Some fixed things, such as eating and sleeping.

We can regard early and late as constructor and destructor, regard a lot of things to be done as events, and regard fixed things as methods.

Because every person's daily life is not necessarily the same, so we cannot write the things we want to do every day! We can define at most some inherent mode method abstractions, such as what we do after getting up, what we do after lunch, and what we do before going to bed. Isn't that an event?

When we design the class, if the class is used sometimes involves some execution process problems, and some unknown things will happen in this process (unknown means that the external class provides, provided by ourselves is known), we will design these unknown into abstract methods.

Because the order of the process is fixed, for example, after lunch, what you do must actually be after lunch, so What things do after lunch cannot be used by others in the morning (You are the God that cannot move the lunch to me for breakfast. If you move it, it will be called after breakfast ).

In the same sense, the execution of an event cannot be determined by the outside. This is the difference between an event and a delegate (the delegate is not restricted in use and can be used anytime, anywhere). This is also the meaning of an event. The entire process is called the "lifecycle ".

The code is so consistent with the reality that it is intriguing.

Ad back ~~ Let's continue to look at the httpapplication events. I posted them in the execution order. The general functions can be seen from the name. Some I have never used :)

Beginrequest // request start

Authenticaterequest
Postauthenticaterequest
Authorizerequest
Postauthorizerequest

Resolverequestcache
Postresolverequestcache

Postmaprequesthandler

Acquirerequeststate // obtain the Request status. At this time, the session already exists.

Postacquirerequeststate

Prerequesthandlerexecute // prepare to be handed over to httphandler for processing

Error // an exception occurred in the request !!!

Postrequesthandlerexecute

Releaserequeststate // status of the publish request

Postreleaserequeststate

Updaterequestcache

Postupdaterequestcache

Endrequest // end the request

Presendrequestheaders // prepare to send the request header information. Here, we can modify the content

Presendrequestcontent // prepare to send the request content, which cannot be changed here

This is the real life cycle, right! The interview questions generally take a test of the lifecycle of the page class, which is outdated. Web development is not only a webform, so the page class has no technical content :)

In httpapplication, execute these events as step and step by step. The following is the code for httpapplication to build step:

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.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(new HttpApplication.CallHandlerExecutionStep(app));     app.CreateEventExecutionSteps(HttpApplication.EventPostRequestHandlerExecute, steps);     app.CreateEventExecutionSteps(HttpApplication.EventReleaseRequestState, steps);     app.CreateEventExecutionSteps(HttpApplication.EventPostReleaseRequestState, steps);     steps.Add(new HttpApplication.CallFilterExecutionStep(app));     app.CreateEventExecutionSteps(HttpApplication.EventUpdateRequestCache, steps);     app.CreateEventExecutionSteps(HttpApplication.EventPostUpdateRequestCache, steps);     this._endRequestStepIndex = steps.Count;     app.CreateEventExecutionSteps(HttpApplication.EventEndRequest, steps);     steps.Add(new HttpApplication.NoopExecutionStep());     this._execSteps = new HttpApplication.IExecutionStep[steps.Count];     steps.CopyTo(this._execSteps);     this._resumeStepsWaitCallback = stepCallback; } 

We can also see the execution sequence from the build sequence. Each step has an execute method and runs one by one. If the program encounters an exception, it jumps out directly. Our page execution is in the callhandlerexecutionstep step.

Okay, let's talk about it? Today, there are fewer Chinese characters and more code. If you have any questions, just comment on them. If you have never used it, just write it. httpmodule is a good thing. PS: How can I implement an abnormal monitoring function for a running website ?" What do you think? :)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.