Ihttpmodule 的一个小问题,今天明白了

本文解析了ASP.NET中HTTPModule的事件绑定机制,重点介绍了如何通过一次绑定实现在每个Web请求时都能触发事件处理的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

         最近有时间看一些.net的框架代码,发现一个有意思的问题,就是HttpModule中的Init函数下的事件绑定,因为事件
的绑定在事件发生后相应的处理委托即为null,但下面的代码(功能:地址的重定向)为什么只是绑定一次后就能在每个
WEB请求过来时都能运行
ReUrl_BeginRequest事件呢。

public class HttpModule : System.Web.IHttpModule
{
     public void Init(HttpApplication context)
     {
  context.BeginRequest += new EventHandler(ReUrl_BeginRequest);
        ....
     }

     private void ReUrl_BeginRequest(object sender, EventArgs e)
     {
         ....
     }


         原因主要是出现System.Web.HttpApplication 中的这个函数HookupEventHandlersForAppplicationAndModules这个函
数(如下)

None.gif
None.gif
private   void  HookupEventHandlersForAppplicationAndModules(MethodInfo[] handlers)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif      
for (int num1 = 0; num1 < handlers.Length; num1++)
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif            MethodInfo info1 
= handlers[num1];
InBlock.gif            
string text1 = info1.Name;
InBlock.gif            
int num2 = text1.IndexOf('_');
InBlock.gif            
string text2 = text1.Substring(0, num2);
InBlock.gif            
object obj1 = null;
InBlock.gif            
if (string.Compare(text2, "Application"true, CultureInfo.InvariantCulture) == 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                  obj1 
= this;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else if (this._moduleCollection != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                  obj1 
= this._moduleCollection[text2];
ExpandedSubBlockEnd.gif            }

InBlock.gif            
if (obj1 != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                  Type type1 
= obj1.GetType();
InBlock.gif                  EventDescriptorCollection collection1 
= TypeDescriptor.GetEvents(type1);
InBlock.gif                  
string text3 = text1.Substring(num2 + 1);
InBlock.gif                  EventDescriptor descriptor1 
= collection1.Find(text3, true);
InBlock.gif                  
if ((descriptor1 == null&& (string.Compare(text3.Substring(02), "on"true, CultureInfo.InvariantCulture) == 0))
ExpandedSubBlockStart.gifContractedSubBlock.gif                  
dot.gif{
InBlock.gif                        text3 
= text3.Substring(2);
InBlock.gif                        descriptor1 
= collection1.Find(text3, true);
ExpandedSubBlockEnd.gif                  }

InBlock.gif                  MethodInfo info2 
= null;
InBlock.gif                  
if (descriptor1 != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                  
dot.gif{
InBlock.gif                        EventInfo info3 
= type1.GetEvent(descriptor1.Name);
InBlock.gif                        
if (info3 != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                              info2 
= info3.GetAddMethod();
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                  }

InBlock.gif                  
if (info2 != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                  
dot.gif{
InBlock.gif                        ParameterInfo[] infoArray1 
= info2.GetParameters();
InBlock.gif                        
if (infoArray1.Length == 1)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                              Delegate delegate1 
= null;
InBlock.gif                              ParameterInfo[] infoArray2 
= info1.GetParameters();
InBlock.gif                              
if (infoArray2.Length == 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                              
dot.gif{
InBlock.gif                                    
if (infoArray1[0].ParameterType != typeof(EventHandler))
ExpandedSubBlockStart.gifContractedSubBlock.gif                                    
dot.gif{
InBlock.gif                                          
goto Label_0168;
ExpandedSubBlockEnd.gif                                    }

InBlock.gif                                    ArglessEventHandlerProxy proxy1 
= new ArglessEventHandlerProxy(this, info1);
InBlock.gif                                    delegate1 
= proxy1.Handler;
ExpandedSubBlockEnd.gif                              }

InBlock.gif                              
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                              
dot.gif{
InBlock.gif                                    
try
ExpandedSubBlockStart.gifContractedSubBlock.gif                                    
dot.gif{
InBlock.gif                                          delegate1 
= Delegate.CreateDelegate(infoArray1[0].ParameterType, this, text1);
ExpandedSubBlockEnd.gif                                    }

InBlock.gif                                    
catch (Exception)
ExpandedSubBlockStart.gifContractedSubBlock.gif                                    
dot.gif{
InBlock.gif                                          
goto Label_0168;
ExpandedSubBlockEnd.gif                                    }

ExpandedSubBlockEnd.gif                              }

InBlock.gif                              
try
ExpandedSubBlockStart.gifContractedSubBlock.gif                              
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif                                    info2.Invoke(obj1, 
new object[] dot.gif{ delegate1 });
ExpandedSubBlockEnd.gif                              }

InBlock.gif                              
catch (Exception)
ExpandedSubBlockStart.gifContractedSubBlock.gif                              
dot.gif{
ExpandedSubBlockEnd.gif                              }

InBlock.gif                        Label_0168:;
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                  }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif      }

ExpandedBlockEnd.gif}

None.gif
None.gif
None.gif
None.gif

         请注意_moduleCollection这个属性,它其实可以理解为一系列的HttpModule的集合,里面的数据主要是我们在web.config
中的内容,如下:
         <httpModules>
         <add type="Discuz.Forum.HttpModule, Discuz.Forum" name="HttpModule" />
          </httpModules>
          上面的代码基本上是找出相关的HTTPMODULE或HANDLER中的绑定事件,然后去运行。
 
          那是什么函数实现了将web.config中的设置获取到_moduleCollection变量中呢,InitModules()这个函数不名思议就是干
这个活的,它的代码如下

None.gif private   void  InitModules()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif      HttpModulesConfiguration configuration1 
= (HttpModulesConfiguration) HttpContext.GetAppConfig("system.web/httpModules");
InBlock.gif      
if (configuration1 == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif            
throw new HttpException(HttpRuntime.FormatResourceString("Missing_modules_config"));
ExpandedSubBlockEnd.gif      }

InBlock.gif      
this._moduleCollection = configuration1.CreateModules();
InBlock.gif      
int num1 = this._moduleCollection.Count;
InBlock.gif      
for (int num2 = 0; num2 < num1; num2++)
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif            
this._moduleCollection[num2].Init(this);
ExpandedSubBlockEnd.gif      }

InBlock.gif      GlobalizationConfig config1 
= (GlobalizationConfig) HttpContext.GetAppConfig("system.web/globalization");
InBlock.gif      
if (config1 != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif            
this._appLevelCulture = config1.Culture;
InBlock.gif            
this._appLevelUICulture = config1.UICulture;
ExpandedSubBlockEnd.gif      }

ExpandedBlockEnd.gif}

None.gif

           另外它还运行了Init方法,而这个方法所干的活就是我们在实现IHTTPMODULE中所希望的操作即:
           {
             context.BeginRequest += new EventHandler(ReUrl_BeginRequest);
              .....
          }

         这样当外部请求来时,系统会运行到System.Web.HttpApplication.InitInternal函数,它会去调用
HookupEventHandlersForAppplicationAndModules,
这样就能在只绑定一次事件之后,即使有新的请求到来是时,系统依然知道要去运行那些要处理的事件。

         这篇文章没有什么技术含量,因为很长时间没写东西了,所以发了出来, 希望大家见谅,献丑了。
 
   
    参考文章:http://www.cnblogs.com/dudu/archive/2006/01/14/317016.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值