原文:A case of lost session variables when using out of process session state
近日某顾客遇到session问题,他如是描述:当SessionState是进程内时,运行正常;一旦切换到进程外,就会发生session内容丢失,web.config中的配置如下:
<sessionState mode="StateServer" cookieless="UseCookies" stateConnectionString="tcpip=127.0.0.1:42424"/>
仔细翻阅了客户发来的报告,发现并不是所有的Session变量都有这个问题,只是在Page_Error事件中设定的Sesion会有这个问题。当发生异常后,在Page_Error中保存错误信息,跳转到自定义错误处理页面(web.config中配置customErrors),读取先前保存的错误信息时什么也没取得。
进程外与进程内有什么区别呢?
进程内:session对象是被保存中进程的内存中, 当执行如下语句时 Session[“mySessionVar”] = “some value”,“some value”被立即写入Session变量中。
而进程外呢(stateserver or sqlsessionstate) ,当前会话的所有Session变量都是在请求开始时从存储空间读入,在请求结束时才向存储空间反映Session值的变化。
从请求开始到结束期间发生异常,请求会被终止,这样在此期间对Session变量的改变不会反映到存储区间,它依然是老样子。
如何处理呢?
在使用进程外SessionState时,当异常发生时,如何在错误处理页面取得先前保存的异常相关信息呢?你得在Page_Error中清空错误,并手动跳转到错误处理页面
代码差不多是这个样子:
protected void Page_Error(object sender, EventArgs e)
{
Session["ErrorPage"] = "Default2.aspx";
Exception ex = Server.GetLastError();
Session["ErrorMessage"] = ex.Message.ToString();
Server.ClearError();
Response.Redirect("~/ErrorPages/ErrorPage.aspx");
}
Server.ClearError()这句使得请求得以正常结束而非中止(aborted),这样先前Session["ErrorMessage"] = ex.Message.ToString()就可以反映到存储空间了。