繁体   English   中英

如何限制每个请求只有一个调用的HttpModule?

[英]How to limit HttpModule with ONLY ONE call per request?

这是我对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)
    {
        ...
    }
}

web.config:

<?xml version="1.0"?>
<configuration>  
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="HttpModuleRewriter" preCondition="managedHandler" type="HttpModuleRewriter" />
    </modules>
  </system.webServer>
</configuration>  

我已经在HttpModuleRewriter类的'Init'方法中放置了断点。 在应用程序启动时将调用第一次方法...并且对页面的每个请求仅调用一次模块。

如果我对页面的请求很快(第二个请求将在处理第一个请求之前发送),那么方法'Init'会被另外调用,每个随后的页面请求都会导致2-3次调用我的模块...

为什么? 我该如何避免呢?

谢谢。

PS我已将公共构造函数添加到HttpModuleRewriter中以计算引用量,并且在我的请求中,我创建了5个模块...并且对于第2页的每个请求,实际上都被调用了...但是仅对于第一个导航页而言,接下来的所有页面(我检查过3个其他页面)模块仅调用一次(仅调用1个实例)...

为什么第一页要处理两次? 建议的答案(使用“已初始化”标志)也无济于事。

如果在第二个请求出现之前Init()尚未完成,则您的HttpModule尚未准备好。 如果您的Init()方法中的代码只能运行一次,则可以设置一个标志(初始化为布尔型)并使用锁来防止代码被多个线程运行,例如:

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;
         }
    }
}

更新:如本文所述 ,ASP.NET可能会创建一个以上的HttpModule实例,因此Init()可以被多次调用。 这是设计使然。 因此,您必须调整模块的样式,以使仅应运行一次的代码仅运行一次-通过应用锁定(如上)。

我想说的显而易见的答案是,您的处理程序正在处理多个请求,可能是样式表或图像。

将以下内容添加到您的ProcessRequest事件处理程序中,并将监视添加到context.Request.PhysicalPath进行确认。

HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;

string filename = Path.GetFileName(context.Request.PhysicalPath);

如果您不希望处理程序为图像等请求运行,您所需要做的就是检查以“ .aspx”结尾的路径或类似内容。

当您两次执行Init()时,BeginRequest事件将调用两次您的处理,因为其中有两个事件处理程序。 + =运算符将新的事件处理程序添加到列表中,它不会替换旧的处理程序。

Øyvind有一个正确的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM