是否可以在IHttpModule

时间:2018-06-07 01:35:11

标签: c# asp.net webforms

如果要使用自定义IHttpModule记录请求,IHttpContext.LogRequest事件似乎是一个自然事件。我面临的问题是我希望将会话ID存储在日志中,但是当LogRequest被命中时,它不适用于大多数请求。

以下是我的代码的简化版本:

public class ActivityTraceModule : IHttpModule, IRequiresSessionState, IReadOnlySessionState
{
    static Logger logger = LogManager.GetCurrentClassLogger();

    public void Init(HttpApplication context) {
        context.LogRequest += OnLogRequest;
    }

    public void OnLogRequest(Object source, EventArgs e) {
        var app = (HttpApplication)source;
        var context = app.Context;
        var sessionId = context.Session != null ? context.Session.SessionID : null;
        logger.Debug("SessionId: " + sessionId);
    }
}

看起来会话状态在LogRequest被点击时已经发布,如此图像所示:

ASP.NET App Lifecycle

我应该使用其他事件来进行记录吗?理想情况下,响应应该已经完全可用。或者有没有办法在我不知道的IHttpContext.LogRequest事件中正确访问会话状态?

1 个答案:

答案 0 :(得分:0)

好吧,我确实没有找到从Session事件中访问请求LogRequest的方法,所以我刚订阅了另一个事件:

public void Init(HttpApplication context) {
    context.PostRequestHandlerExecute += OnLogRequest;
    //context.LogRequest += OnLogRequest;
}

(我知道,我很懒,我没有改变事件处理程序的名称,但那是因为我宁愿让它意味着它的作用而不是附加的事件它:-))

之后,我能够访问具有实际会话的每个请求的会话。

我遇到了另一个"问题"但是:即使在用户注销后,ASP.NET也会重新使用存储在cookie上的会话ID来进行后续请求。因为我想将会话ID用于" group by"每个用户"登录会话"我不得不清除会话ID以强制使用新的会话ID。为了实现这一目标,我创建了一种扩展方法来放弃会话并清除其会话ID:

public static void AbandonAndClearSessionCookie(this HttpSessionState session) {
    session.Clear();
    session.Abandon();
    if (HttpContext.Current != null && HttpContext.Current.Response != null)
        HttpContext.Current.Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
}

注意:此方法不是万无一失的,可以在web.config文件中更改会话ID cookie名称。我大多肯定会改进以前的代码。

然后在用户退出时使用它是一件事:

protected void HeadLoginStatus_LoggingOut(object sender, System.Web.UI.WebControls.LoginCancelEventArgs e) {
    Session.AbandonAndClearSessionCookie();
}

我只是将事件处理程序附加到HeadLoginStatus.LoggingOut事件。

在ASP.NET MVC中,我必须在AuthController.Logout方法上编写它:

public ActionResult Logout() {
    FormsAuthentication.SignOut();
    Session.AbandonAndClearSessionCookie();
    return RedirectToAction("Index", "Home");
}