C# ASP.NET 中的会话超时警告
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10522482/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Session Timeout Warning in ASP.NET
提问by cdub
I have an asp.net site that I need to have a popup/layer/alert happen when the session reaches its timeout (lets say 10 minutes). The popup will say that your account session will exprire due to inactivity and have a button for continue session or a button for logout.
我有一个 asp.net 站点,当会话超时(假设 10 分钟)时,我需要有一个弹出窗口/层/警报发生。弹出窗口会说您的帐户会话将因不活动而过期,并有一个继续会话按钮或一个注销按钮。
I see different ways to do this online, but what's the best/proper way to handle this? Do I have to put an additional timeout if the popup is open too long?
我在网上看到了不同的方法来做到这一点,但是处理这个问题的最佳/正确方法是什么?如果弹出窗口打开时间过长,我是否必须设置额外的超时时间?
采纳答案by Pranay Rana
Check this article , this contains all things what you need for your requirement
查看这篇文章,它包含了满足您要求的所有内容
Alert Session Time out in ASP.NET
<script language="javascript" type="text/javascript">
var sessionTimeoutWarning =
"<%= System.Configuration.ConfigurationSettings.AppSettings
["SessionWarning"].ToString()%>";
var sessionTimeout = "<%= Session.Timeout %>";
var sTimeout = parseInt(sessionTimeoutWarning) * 60 * 1000;
setTimeout('SessionWarning()', sTimeout);
function SessionWarning() {
var message = "Your session will expire in another " +
(parseInt(sessionTimeout) - parseInt(sessionTimeoutWarning)) +
" mins! Please Save the data before the session expires";
alert(message);
}
</script>
回答by StuartLC
This has been addressed before, e.g. ASP.NET - Javascript timeOut Warning based on sessionState timeOut in web.config
之前已经解决了这个问题,例如 ASP.NET - 基于 web.config 中的 sessionState timeOut 的 Javascript 超时警告
However, AFAIK there isn't a totally reliable way to do this, since:
但是,AFAIK 没有完全可靠的方法来做到这一点,因为:
- If the user has more than one window open using the same session, then one window may be more recent than the other and the client session timeouts on the oldest window would be stale / incorrect.
- If you round trip to the server to see what the current session expiration is, you will extend it, thus defeating the purpose of the popup / alert.
- 如果用户使用同一个会话打开了多个窗口,那么一个窗口可能比另一个更新,并且最旧窗口上的客户端会话超时将是陈旧的/不正确的。
- 如果您往返于服务器以查看当前会话到期时间是什么,您将延长它,从而破坏弹出/警报的目的。
回答by Joseph Caruana
You will have to use client side technology for here (javascript). Using for example you would use javascript timeout facility and then show the warning. If user clicks ok you can need to do something to keep the session alive. I would sugest using jquery.ajax method, and making a call to the server, can be a dummy call - just to keep the session alive.
您将不得不在此处使用客户端技术(javascript)。例如,您将使用 javascript 超时工具,然后显示警告。如果用户点击确定,您可能需要做一些事情来保持会话的活动。我会建议使用 jquery.ajax 方法,并调用服务器,可以是一个虚拟调用 - 只是为了保持会话活跃。
回答by Samuel G
You could you jquery and the setinterval function to do an Ajax post behind the scenes to refresh the timeout, if using sliding expiration, or get the value of time remaing by recording the session start time and subtracting from the expiration time.
如果使用滑动过期,您可以使用 jquery 和 setinterval 函数在后台执行 Ajax 帖子以刷新超时,或者通过记录会话开始时间并从过期时间中减去来获取剩余时间的值。
回答by UTHIRASAMY
What you can do is use some javascript to fire the message. Use a timer to fire after a certain period (period set for session time out in your application - a couple of minutes).
您可以做的是使用一些 javascript 来触发消息。使用计时器在一段时间后触发(在您的应用程序中为会话超时设置的时间段 - 几分钟)。
After that period, show a confirmation dialog to the user that session will time out. If the user clicks to keep the sesion. Make a dummy postback in the page so that the session is not lost. You can also make an AJAX call so that user does not see the page reloading and loses input data.
在那段时间之后,向用户显示会话将超时的确认对话框。如果用户单击以保留会话。在页面中进行虚拟回发,以便会话不会丢失。您还可以进行 AJAX 调用,这样用户就不会看到页面重新加载和丢失输入数据。
回答by moomoo
Below is some JavaScript with jQuery to warn the user about ASP.NET Forms Authentication timeout and will redirect them to the login page if timeout is reached. It could be improved and adapted for session timeout as well. It will also reset the authentication timeout by "pinging" the server whenever the user interacts with the page by clicking, typing or resizing.
下面是一些带有 jQuery 的 JavaScript,用于警告用户有关 ASP.NET 表单身份验证超时的信息,并在超时时将它们重定向到登录页面。它也可以针对会话超时进行改进和调整。每当用户通过单击、键入或调整大小与页面交互时,它还会通过“ping”服务器来重置身份验证超时。
Note that this does add load to the server by pinging with every click, key press, resize but it's pretty minimal. Still, if you have many users typing away you will need to evaluate the impact. I couldn't think of another way to do this because the server has to be involved since that's where the timeout is expiring.
请注意,这确实会通过每次单击、按键、调整大小进行 ping 操作来增加服务器的负载,但它非常小。尽管如此,如果您有很多用户打字,您将需要评估影响。我想不出另一种方法来做到这一点,因为必须涉及服务器,因为那是超时到期的地方。
Also note that the timeout is not hard-coded in the JS. It get's the timeout from the server so you only need to maintain it in one place in Web.config.
另请注意,超时不是在 JS 中硬编码的。它从服务器获取超时,因此您只需要在 Web.config 中的一个地方维护它。
(function ($, undefined) {
if (!window.session) {
window.session = {
monitorAuthenticationTimeout: function (redirectUrl, pingUrl, warningDuration, cushion) {
// If params not specified, use defaults.
redirectUrl = redirectUrl || "~/Account/Login";
pingUrl = pingUrl || "~/Account/Ping";
warningDuration = warningDuration || 45000;
cushion = cushion || 4000;
var timeoutStartTime,
timeout,
timer,
popup,
countdown,
pinging;
var updateCountDown = function () {
var secondsRemaining = Math.floor((timeout - ((new Date()).getTime() - timeoutStartTime)) / 1000),
min = Math.floor(secondsRemaining / 60),
sec = secondsRemaining % 60;
countdown.text((min > 0 ? min + ":" : "") + (sec < 10 ? "0" + sec : sec));
// If timeout hasn't expired, continue countdown.
if (secondsRemaining > 0) {
timer = window.setTimeout(updateCountDown, 1000);
}
// Else redirect to login.
else {
window.location = redirectUrl;
}
};
var showWarning = function () {
if (!popup) {
popup = $(
"<div style=\"text-align:center; padding:2em; color: black; font-color: black; background-color:white; border:2px solid red; position:absolute; left: 50%; top:50%; width:300px; height:120px; margin-left:-150px; margin-top:-90px\">" +
"<span style=\"font-size:1.4em; font-weight:bold;\">INACTIVITY ALERT!</span><br/><br/>" +
"You will be automatically logged off.<br/><br/>" +
"<span style=\"font-size:1.4em; font-weight:bold;\" id=\"countDown\"></span><br/><br/>" +
"Click anywhere on the page to continue working." +
"</div>")
.appendTo($("body"));
countdown = popup.find("#countDown");
}
popup.show();
updateCountDown();
};
var resetTimeout = function () {
// Reset timeout by "pinging" server.
if (!pinging) {
pinging = true;
var pingTime = (new Date()).getTime();
$.ajax({
type: "GET",
dataType: "json",
url: pingUrl,
}).success(function (result) {
// Stop countdown.
window.clearTimeout(timer);
if (popup) {
popup.hide();
}
// Subract time it took to do the ping from
// the returned timeout and a little bit of
// cushion so that client will be logged out
// just before timeout has expired.
timeoutStartTime = (new Date()).getTime();
timeout = result.timeout - (timeoutStartTime - pingTime) - cushion;
// Start warning timer.
timer = window.setTimeout(showWarning, timeout - warningDuration);
pinging = false;
});
}
};
// If user interacts with browser, reset timeout.
$(document).on("mousedown mouseup keydown keyup", "", resetTimeout);
$(window).resize(resetTimeout);
// Start fresh by reseting timeout.
resetTimeout();
},
};
}
})(jQuery);
Simply call the above once when your page loads:
当您的页面加载时,只需调用上述一次:
window.session.monitorAuthenticationTimeout(
"/Account/Login", // You could also use "@FormsAuthentication.LoginUrl" in Razor.
"/Account/Ping");
On the server, you'll need an action that returns the remaining time. You could add more information as well.
在服务器上,您需要一个返回剩余时间的操作。您也可以添加更多信息。
public JsonResult Ping()
{
return Json(new {
timeout = FormsAuthentication.Timeout.TotalMilliseconds
},
JsonRequestBehavior.AllowGet);
}
回答by Damian Vogel
I went to see the article from the postof Pranay Rana, and I like the general idea, but the code could use some streamlining. So here is my version. For tablet / mobile issues see below:
我去看了Pranay Rana的帖子,我喜欢总体思路,但代码可以使用一些精简。所以这是我的版本。对于平板电脑/移动设备问题,请参见下文:
<script language="javascript" type="text/javascript">
var minutesForWarning = 4;
var sessionTimeout = parseInt("@Session.Timeout"); // razor syntax, otherwise use <%= Session.Timeout %>
var showWarning = true;
function SessionWarning() {
showWarning = false;
alert("Your session will expire in " + minutesForWarning + " mins! Please refresh page to continue working.");
// leave a second for redirection fct to be called if expired in the meantime
setTimeout(function () { showWarning = true; }, 1000);
}
function RedirectToWelcomePage() {
if (showWarning)
alert("Session expired. You will be redirected to welcome page.");
document.getElementById('logoutForm').submit();
// window.location = "../Welcome.aspx"; // alternatively use window.location to change page
}
setTimeout('SessionWarning()', (sessionTimeout - minutesForWarning) * 60 * 1000);
setTimeout('RedirectToWelcomePage()', sessionTimeout * 60 * 1000);
</script>
Well, on tablets or mobiles, you can't count on the setTimeout, as javascript execution is suspended when the device is locked or browser inactive. Instead, I'm doing a periodical check (in my case, I esteem every 10s to be enough):
好吧,在平板电脑或手机上,您不能指望 setTimeout,因为当设备被锁定或浏览器处于非活动状态时,javascript 执行会暂停。相反,我正在进行定期检查(就我而言,我认为每 10 秒就足够了):
<script language="javascript" type="text/javascript">
function addMinutes(date, minutes) {
return new Date(date.getTime() + minutes * 60 * 1000);
}
function remainingMinutes(date) {
return Math.round((date - (new Date()).getTime()) / 60 / 1000);
}
var minutesForWarning = 5;
var sessionTimeout = parseInt("@Session.Timeout");
var showWarning = true;
var showRedirect = true;
var timeToWarn = addMinutes(new Date(), sessionTimeout - minutesForWarning);
var timeToEnd = addMinutes(new Date(), sessionTimeout);
function CheckTime() {
if (showWarning && new Date() > timeToWarn && new Date() < timeToEnd) {
showRedirect = false;
showWarning = false;
alert("Your session will expire in " + remainingMinutes(timeToEnd)) + " mins! Please refresh page to continue working.");
}
if (new Date() > timeToEnd) {
if (showRedirect)
alert("Session expired. You will be redirected to welcome page ");
document.getElementById('logoutForm').submit();
// window.location = "../Welcome.aspx"; // alternatively use window.location to change page
}
if (showRedirect == false)
showRedirect = true;
}
setInterval(CheckTime, 10000);
</script>

