我实现了从a control by Kenneth Scott派生的自定义ASP.NET会话超时控件。它由.NET 4中的.NET 4托管。
长话短说,它是我在网站母版页中包含的服务器控件(实现System.Web.UI.WebControls.WebControl)。该控件是不可见的,并在呈现页面时启动计时器。在X分钟过去之后,会显示一个DIV,告诉用户他们的会话超时,如果他们想要保持登录状态,则为他们提供一个单击按钮。
单击该按钮只会触发标准回发到服务器。除了重置会话的滑动到期外,它不会在服务器上执行任何有用的工作。
超时控件配置为在会话到期前一分钟启动。当它达到0时,会话也应该到期,我将用户重定向到登录页面并通知他们由于不活动而超时。
大部分时间都很好用,但有时“不起作用”。该按钮似乎仍然适用于用户,但在尝试单击站点上的任何其他控件后,它们会立即转储到登录页面(web.config中定义的标准ASP.NET行为)。
我在click事件处理程序中添加了一些日志记录语句,发现它没有触发。我的假设是客户端向服务器发送请求,但由于会话过期,我的事件处理程序永远不会触发。
我确信我的应用程序池没有被回收(它被配置为每天回收一次,并且没有进程或粘性指令管理员正在编辑应用程序目录中的文件)。这种失败是间歇性发生的。我们正在使用表单身份验证。
我在web.config中的system.web部分:
<sessionState mode="InProc" timeout="20" />
<authentication mode="Forms">
<forms path="/" loginUrl="Pages/LoginPage.aspx" protection="All" timeout="20" slidingExpiration="true" />
</authentication>
我目前的解决方法是增加会话并将表单超时设置为30分钟,并为超时引入新的配置设置,该设置仍会在20分钟后将用户注销。额外的10分钟提供足够的填充,我的控件按预期工作。
我不喜欢这个解决方案,因为它最好是解决方法。我觉得我不能充分理解ASP.NET会话超时机制(尽管已阅读并重读了MSDN文档)。任何人都可以解释我所看到的行为,或者指出我正在做的任何错误的假设吗?
答案 0 :(得分:3)
您可以尝试记录任何应用程序结尾以及结束的原因,只是为了排除它与此有关。我总是使用这个脚本(只需将它放在global.asax中):
protected void Application_End()
{
Type httpRuntimeType = typeof (HttpRuntime);
HttpRuntime runtime =
(HttpRuntime)
httpRuntimeType.InvokeMember("_theRuntime", BindingFlags.NonPublic
| BindingFlags.Static |
BindingFlags.GetField,
null, null,
null);
if (runtime == null)
return;
string shutDownMessage =
(string) runtime.GetType().InvokeMember("_shutDownMessage",
BindingFlags.NonPublic
| BindingFlags.Instance
| BindingFlags.GetField,
null,
runtime,
null);
string shutDownStack =
(string) runtime.GetType().InvokeMember("_shutDownStack",
BindingFlags.NonPublic
| BindingFlags.Instance
| BindingFlags.GetField,
null,
runtime,
null);
EventLog log = new EventLog();
log.Source = ".NET Runtime";
log.WriteEntry(
String.Format(
"\r\n\r\n_shutDownMessage={0}\r\n\r\n_shutDownStack={1}",
shutDownMessage,
shutDownStack),
EventLogEntryType.Information);
}