簡體   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