【问题标题】:Sessions and server variables in Session_EndSession_End 中的会话和服务器变量
【发布时间】:2011-01-12 22:55:11
【问题描述】:

我有一个具有以下实现的 InProc 会话网站:

protected void Session_End(object sender, EventArgs e)
        {
            StreamWriter sw = null;
            string logFile = Server.MapPath("testSessionLog.txt");
            sw = new StreamWriter(logFile, true);
            sw.WriteLine("Session_End called at " + DateTime.Now);
            try
            {
                //Request is not available in this context 
                if (Request.ServerVariables["Logon_User"] != null && Request.ServerVariables["Logon_User"] != "")
                {
                    sw.WriteLine("Made it past Request.ServerVariables check");
                }
            }
            catch (Exception ex)
            {
                sw.Write("An error occured: " + ex.Message);
            }
            finally
            {
                sw.Close();
            }         
        }

我在堆栈上阅读了几篇文章 (1,2),其中详细介绍了如何使用 this.Session 访问 HttpSessionState。 Server.MapPath() 和 Request.ServerVariables() 呢?我也无法让这些在 Session_End 中工作。

我将相同的代码块粘贴到 button_Click 事件中,它运行没有问题。这让我相信它与 Session_End 有关。

我将 IIS6 设置为每分钟循环一次。当我有一个公开会议时,它会爆发: 错误:
异常类型:HttpException
异常消息:服务器操作在此上下文中不可用

在事件查看器中,它显示为事件 1309。它抱怨包含 Server.MapPath() 的行

【问题讨论】:

    标签: asp.net iis-6


    【解决方案1】:

    如前所述,在调用 Session_End 时没有可使用的 HttpContext 对象,因此访问 ie。 ServerVariables 一点意义都没有。

    对于MapPath,您可以调用静态方法HostingEnvironment.MapPath(),它不依赖于请求。

    http://msdn.microsoft.com/en-us/library/system.web.hosting.hostingenvironment.mappath.aspx

    【讨论】:

    • 我们使用ServerVariables来获取用户的UserName。由于所有用户都在域上,我不明白当还有 this.Session 时如何获取 Logon_User 是没有意义的。除非您告诉我 Session_End 中的 this.Session 是由系统触发且仅包含系统信息的会话。是这样吗?
    • 是的。 Session_End 在您无法控制的任意点触发。可能是在半夜,您的用户早已不在并且睡得很紧。需要了解的重要一点是,没有可访问的 HttpContext,因为在某些请求期间不会触发事件。
    【解决方案2】:

    问题是 session_end 不是从请求中触发的。它是由服务器上的超时触发的,在会话上的最后一个请求被处理很久之后。所以,没有请求对象。

    如果您在会话中调用了 Abandon,这可能不是真的(因为您已经在请求的上下文中这样做了)。我还没有尝试过,但我怀疑它也不起作用。

    我不知道 MapPath - 也许它需要一个实时请求来做它的事情。

    【讨论】:

    • 您会认为系统知道要结束哪个会话,因此可以将一些原始会话数据关联回 this.Session 并将其存储在 this.Session.original 中,然后再将其删除...
    • 您在寻找 Request 数据,而 Session_End 中没有 Request 对象。如果您需要访问那里的内容(例如,作为用户 ID 或其他内容),则将其显式存储在会话中:Session["UserId"] = _userId
    • 我实际上不确定我们在寻找什么。有 12 个应用程序,我没有写任何一个。我只是在排查为什么我们每天会出现 100 多个错误。由于我在下面发布的“解决方案”消除了错误,这就是“修复”。
    • 好吧,祝你好运 - 我讨厌处理别人糟糕的代码(我宁愿自己工作......)
    【解决方案3】:

    毕竟可以访问请求和服务器。您必须分别使用 HttpContext.Current.Request 和 HttpContext.Current.Server。不是会话。 stack. 上对两者进行了很好的比较

    【讨论】:

    • 你无法访问HttpContext
    猜你喜欢
    • 1970-01-01
    • 2017-03-13
    • 1970-01-01
    • 2016-12-22
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多