日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

实现IHttpModule接口获取Session来实现页面访问日志功能。

發(fā)布時間:2025/5/22 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实现IHttpModule接口获取Session来实现页面访问日志功能。 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我們在開發(fā)企業(yè)Web應用程序時經(jīng)常需要對用戶的操作記錄日志,以便在發(fā)生突發(fā)事件后有據(jù)可查,比如要對用戶訪問的每一個頁面都做日志記錄。通常的做法可能是編寫一個記錄日志的方法(如:AddAccessLog),在每一個頁面的Page_Load事件中調(diào)用這個AddAccessLog方法,從而達到記錄頁面訪問日志的目的。這樣的方法在頁面較少的時候可行,但是當項目變得越來越大,需要記錄日志的頁面越來越多的時候,我們要在每個頁面中都調(diào)用這樣的方法,從而使得系統(tǒng)很難維護。有沒有簡單一點的辦法呢,何不用IHttpModule接口實現(xiàn)一個自定義的LogHttpModule來試試呢?

IHttpModule接口中定義了兩個方法:Init和Dispose。Init方法初始化一個模塊,并為它做好處理請求的準備。這時,我們同意接受感興趣的事件通知。Dispose方法處置該模塊使用資源。Init方法接受一個服務該請求的HttpApplication對象的引用。使用該引用可以連接到系統(tǒng)事件。

class PageLoggerModule : IHttpModule? //實現(xiàn)IHttpModule接口
{

public void Dispose()
{
}

public void Init(HttpApplication context)
{
??? context.BeginRequest += new EventHandler(context_BeginRequest);
}

void context_BeginRequest(object sender, EventArgs e)
{

//在這里實現(xiàn)具體代碼

HttpApplication app = (HttpApplication)sender;
HttpContext ctx = app.Context;

//acquire session state
string userId = "Not Registered";
if (ctx.Session != null && ctx.Session["userId"] != null)
{
??? userId = ctx.Session["userId"].ToString();
}

//acquire request string
string funcId = "Init funcId";
if (ctx.Request.QueryString["funcId"] != null)
{
??? funcId = ctx.Request.QueryString["funcId"].ToString();
}

LogEntry log = new LogEntry(); // 這里是自定義的一個類,屬性列表和數(shù)據(jù)庫中的字段一致
log.DateTime = System.DateTime.Now;
log.IpAddress = ctx.Request.UserHostAddress;
log.MachineName = ctx.Request.UserHostName;
log.UserId = userId;
log.FunctionId = funcId;

string logString = log.DateTime.ToString() + "<br/>"
+ log.UserId + "<br/>"
+ log.IpAddress + "<br/>"
+ log.MachineName + "<br/>"
+ log.FunctionId + "<br/>";

//you can add other codes here
ctx.Response.AppendHeader("Author", "Changyu Du");

ctx.Response.Write(logString);

}

}

在Web.config中,System.Web節(jié)中增加一個HttpModule:

??? <httpModules>
?????? <add name="PageLoggerHttpModule" type="PageLoggerHttpModule.PageLoggerModule,PageLoggerHttpModule"/>
??? </httpModules>

新建一個普通的aspx頁面,在頁面加載時把用戶信息保存到Session中,模擬一下項目應用中的情形:

protected void Page_Load(object sender, EventArgs e)
{
??? //Add userName into SESSION
??? if (Session["userId"] == null)
??? {
??????? Session["userId"] = "1101";
??? }
??? else
??? {
??????? Response.Write("SESSION :userId = "+Session["userId"].ToString());
??? }
}

為了確保把用戶Id信息加入到session中,測試頁面上還隨便加了個button,button_click什么都不干,就是為了讓頁面回發(fā)一下確保把userId存入到Session中去。F5運行一下,嗯,不錯,LogEntry的信息都輸出出來了,已經(jīng)取得了訪問時間,IP地址之類的信息,基本成功!下來直接把LogEntry的信息保存到數(shù)據(jù)庫就OK了。

可是,別忙,怎么總?cè)〔坏絊ession中的用戶信息呢?記錄訪問日志用戶Id這樣的信息肯定是需要記錄的啊!

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

下面是MSDN上提供的事件觸發(fā)順序:

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

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

  • 如果已在 Web.config 文件的 UrlMappingsSection 節(jié)中配置了任何 URL,則執(zhí)行 URL 映射。

  • 引發(fā) BeginRequest 事件。

  • 引發(fā) AuthenticateRequest 事件。

  • 引發(fā) PostAuthenticateRequest 事件。

  • 引發(fā) AuthorizeRequest 事件。

  • 引發(fā) PostAuthorizeRequest 事件。

  • 引發(fā) ResolveRequestCache 事件。

  • 引發(fā) PostResolveRequestCache 事件。

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

  • 引發(fā) PostMapRequestHandler 事件。

  • 引發(fā) AcquireRequestState 事件。

  • 引發(fā) PostAcquireRequestState 事件。

  • 引發(fā) PreRequestHandlerExecute 事件。

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

  • 引發(fā) PostRequestHandlerExecute 事件。

  • 引發(fā) ReleaseRequestState 事件。

  • 引發(fā) PostReleaseRequestState 事件。

  • 如果定義了 Filter 屬性,則執(zhí)行響應篩選。

  • 引發(fā) UpdateRequestCache 事件。

  • 引發(fā) PostUpdateRequestCache 事件。

  • 引發(fā) EndRequest 事件。

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

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

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

    void context_AcquireRequestState(object sender, EventArgs e)
    {

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

    //把LogEntry中的信息保存到數(shù)據(jù)庫

    }

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

    ?

    為方便我把源代碼貼出來吧:其中保護我上一片blog《自己編寫B(tài)uildProvider來實現(xiàn)ORM以及BuildProvider的調(diào)試》的代碼:

    CustomBuilderProvider.rar?????? 299KB????? 2008/3/7 22:07:36
    Download

    轉(zhuǎn)載于:https://www.cnblogs.com/junqilian/archive/2008/03/07/1095454.html

    總結(jié)

    以上是生活随笔為你收集整理的实现IHttpModule接口获取Session来实现页面访问日志功能。的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。