首页 > 解决方案 > 是否可以在 IHttpModule 中访问 IHttpContext.LogRequest 中的 SessionId

问题描述

IHttpContext.LogRequest如果您想使用自定义 IHttpModule 记录请求,则该事件似乎是一个很自然的事件。我面临的问题是我想将会话 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 应用程序生命周期

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

标签: c#asp.netwebforms

解决方案


好吧,我真的没有找到SessionLogRequest事件中访问请求的方法,所以我只是订阅了另一个事件:

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

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

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

不过,我遇到了另一个“问题”:ASP.NET 将存储在 cookie 中的会话 ID 重用于后续请求,即使在用户注销之后也是如此。由于我想使用会话 ID 来“分组”每个用户的“登录会话”,因此我必须清除会话 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");
}

推荐阅读