如何限制HttpModule每个请求只有一个呼叫?

Bud*_*dda 1 c# asp.net httpmodule

这是我对HttpModule的实现:

带模块的文件:

public class HttpModuleRewriter : IHttpModule
{
    #region IHttpModule

    public void Init(HttpApplication app)
    {
        app.BeginRequest += ProcessRequest;
    }

    public void Dispose()
    {
    }

    #endregion

    #region Protected Methods

    protected void ProcessRequest(object sender, EventArgs e)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

web.config中:

<?xml version="1.0"?>
<configuration>  
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="HttpModuleRewriter" preCondition="managedHandler" type="HttpModuleRewriter" />
    </modules>
  </system.webServer>
</configuration>  
Run Code Online (Sandbox Code Playgroud)

我在HttpModuleRewriter类的'Init'方法中加入了断点.应用程序启动时调用第一次方法...每个页面请求只调用一次模块.

如果我快速请求页面(第二个请求将在第一个请求被处理之前发送),那么方法"初始化"会被少量调用,每个跟随页面的请求会导致2-3次调用我的模块...

为什么?我怎么能避免这种情况?

谢谢.

PS我已经添加了公共构造成HttpModuleRewriter计算引用的数量,并在我的请求,我有5个模块创建...并为每个请求第2个模块实际上是所谓的...但只适用于第一个导航页中,所有后续页面(我已经检查了3个其他页面)模块只被调用一次(只调用了1个实例)...

为什么第一页被处理两次?建议的答案(使用'初始化'标志)也没有帮助.

Øyv*_*ind 5

如果在第二个请求出现之前Init()还没有完成,那么你的HttpModule还没有准备好.如果您的Init()方法中的代码只能运行一次,那么您可以设置一个标志(bool初始化)并使用锁来防止代码由多个线程运行,例如:

private static bool initialised;
private static object lockObject = new object();

public void Init(HttpApplication app)
{
    lock(lockObject)
    {
         if(!initialised)
         {
           app.BeginRequest += ProcessRequest;
           //... other code here
           initialised = true;
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:正如本文所解释的,ASP.NET可能会创建多个HttpModule实例,因此可以多次调用Init().这是设计的.因此,您必须设计模块,以便应该只运行一次的代码只运行一次 - 通过应用锁定,如上所述.