如果要使用自定义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
被点击时已经发布,如此图像所示:
我应该使用其他事件来进行记录吗?理想情况下,响应应该已经完全可用。或者有没有办法在我不知道的IHttpContext.LogRequest
事件中正确访问会话状态?
答案 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");
}