利用HttpModule開發asp.net頁面、ashx等訪問時session失效的統一處理入口


web程序時,當使用session時總會出現失效而報“未將對象引用設置到對象的實例”的http 500錯誤,本人比較懶,不想每個地方都用try catch處理,就找到個用httpModule統一處理的方法:

1、新建一個_httpmodule的類,繼承IHttpModule接口,為了能在類里面讀取session,添加using System.Web.SessionState;,並繼承IReadOnlySessionState接口;

2、添加application的AcquireRequestState處理:

 void context_AcquireRequestState(object sender, EventArgs e)
    {

        HttpApplication application = (HttpApplication)sender;
        HttpContext context = application.Context;
        context_AcquireRequestState(context, new EventArgs());

    }

    void context_AcquireRequestState(HttpContext context, EventArgs e)
    {


        try
        {
            if (!context.Request.Path.ToString().Contains("login.aspx"))            {
                context.Session["loginUser"].ToString();
            }

        }
        catch (Exception ex)
        {

            context.Response.Write("{'error':false,'message':'尚未登錄!'}");
            context.Response.End();
        }
    }

 

3、添加init,里面注冊AcquireRequestState事件:

 public void Init(HttpApplication context)
    {

        context.AcquireRequestState += new EventHandler(context_AcquireRequestState);

    }

4、webconfig <system.web>節配置:

 <httpModules>
      <add name="123" type="_httpmodule"/>
</httpModules>

這樣當session失效的時候放回錯誤信息,前台ajax處理返回Json即可。

ps:剛開始我將2、3注冊成BeginRequest,可是總取不到Session中的用戶信息, 搜索后發現一篇blog(http://www.cnblogs.com/junqilian/archive/2008/03/07/1095454.html),轉載如下:

可是,別忙,怎么總取不到Session中的用戶信息呢?記錄訪問日志用戶Id這樣的信息肯定是需要記錄的啊!

后來放狗一搜才發現,還是對aspnet的事件處理流程不理解,Begin_Request時還沒有加載Session狀態呢,自然就取不到了。

下面是MSDN上提供的事件觸發順序:

在處理該請求時將由 HttpApplication 類執行以下事件。希望擴展 HttpApplication 類的開發人員尤其需要注意這些事件。

  1. 對請求進行驗證,將檢查瀏覽器發送的信息,並確定其是否包含潛在惡意標記。有關更多信息,請參見 ValidateRequest腳本侵入概述

  2. 如果已在 Web.config 文件的 UrlMappingsSection 節中配置了任何 URL,則執行 URL 映射。

  3. 引發 BeginRequest 事件。

  4. 引發 AuthenticateRequest 事件。

  5. 引發 PostAuthenticateRequest 事件。

  6. 引發 AuthorizeRequest 事件。

  7. 引發 PostAuthorizeRequest 事件。

  8. 引發 ResolveRequestCache 事件。

  9. 引發 PostResolveRequestCache 事件。

  10. 根據所請求資源的文件擴展名(在應用程序的配置文件中映射),選擇實現 IHttpHandler 的類,對請求進行處理。如果該請求針對從 Page 類派生的對象(頁),並且需要對該頁進行編譯,則 ASP.NET 會在創建該頁的實例之前對其進行編譯。

  11. 引發 PostMapRequestHandler 事件。

  12. 引發 AcquireRequestState 事件。

  13. 引發 PostAcquireRequestState 事件。

  14. 引發 PreRequestHandlerExecute 事件。

  15. 為該請求調用合適的 IHttpHandler 類的 ProcessRequest 方法(或異步版 BeginProcessRequest)。例如,如果該請求針對某頁,則當前的頁實例將處理該請求。

  16. 引發 PostRequestHandlerExecute 事件。

  17. 引發 ReleaseRequestState 事件。

  18. 引發 PostReleaseRequestState 事件。

  19. 如果定義了 Filter 屬性,則執行響應篩選。

  20. 引發 UpdateRequestCache 事件。

  21. 引發 PostUpdateRequestCache 事件。

  22. 引發 EndRequest 事件。

AcquireRequestState事件,當實際服務請求的處理程序獲得與該請求關聯的狀態信息時發生。在這個事件發生時才能取到Session中是userId信息。BeginRequest事件在AcquireRequestState之前發生,我們把取Session狀態的代碼放在BeginRequest中肯定是取不到的。

問題找到了,把日志記錄代碼放在AcquireRequestState中就可以了,於是改成下面的樣子:

public void Init(HttpApplication context)
{
    context.AcquireRequestState += new EventHandler(context_AcquireRequestState);
}

void context_AcquireRequestState(object sender, EventArgs e)
{

  //原先context_BeginRequest中的代碼,不重復貼占地方了 :)

//把LogEntry中的信息保存到數據庫

}

好了,這樣我們繼承了IHttpModule接口,實現了一個自定義的LogMudule,這樣在用戶方面每個頁面時,都會自動記錄用戶的信息記如訪問日志數據庫中,再也不用到每個頁面的Page_Load中去寫了,維護起來也方便多了! Yeah~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM