Каков наилучший способ показать сообщение пользователю после окончания сессии? К тому времени пользователь должен быть выведен из системы и перенаправлен на стартовую страницу. Я могу использовать javascript для перенаправления пользователя на стартовую страницу. Я просто хочу показать сообщение на стартовой странице.Уведомлять пользователя, когда время сеанса в asp.net
ответ
В вашей переадресации JavaScript добавьте параметр querystring к URL-адресу переадресации.
<script>
...
// If session is about to timeout...
location.href = '/home.aspx?action=expired';
...
</script>
Затем в начальной странице, вы можете иметь код для проверки строки запроса и отображать сообщение, если это так.
<%
'home.aspx
If Request.QueryString("action") = "expired" Then
Response.Write("<p>You have been logged out due to inactivity.</p>")
End If
%>
Обычно страница будет использовать JavaScript для хранения таймера и отображения всплывающего окна или сообщения dhtml минут или двух до сеанс истекает. Мой банк делает это.
Это очень раздражает, потому что, если у пользователя есть несколько вкладок, открытых для одного и того же сайта, одна вкладка будет знать, что сессия истечет, но другая вкладка не будет, поэтому вы можете получить предупреждение, даже если оно не правда. Если вы попытаетесь использовать вызов AJAX для запроса сервера на время до истечения срока действия сеанса, вы просто увеличили время ожидания сеанса и фактически сделали сеанс никогда не истекающим, пока открыто окно браузера (что может быть не так уж плохо в зависимости от вашей конкретной ситуации).
Эй, сам .. шип, который я нокаутировал прошлой ночью, решает все эти проблемы и обеспечивает ссылочную реализацию как для состояния сеанса, так и для форм auth. может быть, какой-то банк должен нанять меня ... ;-) –
@Sky, я уверен, что вы переоценены для моего банка. Они, по-видимому, только нанимают идиотов. –
Предыдущая версия этого ответа содержит простой источник для решения вопроса, который больше не существует.
Сценарий был, что он хотел быть уведомлен перед тем сеанса истекло, так что могут быть приняты меры.
Неясно, было ли это сеансом asp.net или билетом проверки подлинности форм, но на самом деле это та же проблема.
В основном это управление состоянием сеанса асинхронного сеанса без запуска обновления сеанса/билета. Общее желание для приложений ajax.
Решение довольно простое, но не совсем прямое. Есть немало проблем для решения, но я разработал решение, которое работает как для простого состояния сеанса, так и для проверки подлинности форм.
Он составлен из очень легкого httpmodule и сопутствующей клиентской библиотеки скриптов, и не более 50 или 60 эффективных строк кода.
Стратегия заключается в предоставлении конечной точки http, которая может запрашивать состояние истечения срока действия сеанса или билета формы, не обновляя их. Модуль просто сидит на передней части конвейера и обслуживает пару «виртуальных» конечных точек с датами javascript и очень простой js lib для совершения вызовов.
Демо и источник здесь: AsynchronousSessionAuditor
Некоторые из вас задаются вопросом, почему я бы иметь дело с этим, но, вероятно, больше из вас говорят ад да, что боль в patoot. Я знаю, что в прошлом я придумал хрупкие вонючие обходные пути, и я очень доволен этим.
Он может служить в стандартном приложении с обратной почтой или, скорее, в приложении ajax. Также ... Вы можете узнать больше о жизненном цикле запроса Http here и here. Если интересно, узнайте больше об использовании raw xmlhttp для конечных точек asp.net here
Сокращение предыдущего кода спайка. проверьте историю изменений, если вы заинтересованы.
Вот соответствующие исходные файлы. Полная ссылочная реализация доступна по ссылке, приведенной выше ....
HttpModule
// <copyright project="AsynchronousSessionAuditor" file="AsynchronousSessionAuditorModule.cs" company="Sky Sanders">
// This source is a Public Domain Dedication.
// http://spikes.codeplex.com
// Attribution is appreciated.
// </copyright>
using System;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
namespace Salient.Web.Security
{
/// <summary>
/// AsynchronousSessionAuditorModule provides a mechanism for auditing the lifecycle
/// of an ASP.Net session and/or an ASP.Net FormsAuthentication cookie in the interest
/// of providing better monitoring and control of a user session. This is becoming more
/// important as more and more web apps are single page apps that may not cycle a page for
/// many minutes or hours.
///
/// Storing a token in the Asp.net Session was for many years the default authentication strategy.
/// The are still valid applications for this techique although FormsAuthentication has far
/// surpassed in security and functionality.
///
/// What I am providing is a manner in which to transparently monitor the expiration status of each
/// by implementing a module that recognizes two virtual endpoints:
///
/// http://mysite/.aspnetsession
/// http://mysite/.formsauthticket
///
/// By making a request to these urls you will be delivered a javascript date in numeric form that
/// represents the expiration dateTime of either the current ASP.Net session, if any, or the current
/// FormsAuthentication ticket expiration, if any.
///
/// If the requested item does not exists, zero is returned. Any value served by this module should
/// be cast to a date and compared with Now. If less than you should take action. You should have
/// taken action on the client before the session timed out, aided by the output of this module, but
/// hey, nobody is perfect.
/// </summary>
public class AsynchronousSessionAuditorModule : IHttpModule
{
// note: these must remain in sync with the string keys in the javascript
private const string AspSessionAuditKey = ".aspnetsession";
private const string FormsAuthAuditKey = ".formsauthticket";
#region IHttpModule Members
public void Init(HttpApplication context)
{
// this is our audit hook. get the request before anyone else does
// and if it is for us handle it and end. no one is the wiser.
// otherwise just let it pass...
context.BeginRequest += HandleAuditRequest;
// this is as early as we can access session.
// it is also the latest we can get in, as the script handler is coming
// right after and we want to beat the script handler to the request
// will have to set a cookie for the next audit request to read in Begin request.
// the cookie is used nowhere else.
context.PostAcquireRequestState += SetAuditBugs;
}
public void Dispose()
{
}
#endregion
private static void SetAuditBugs(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication) sender;
if ((app.Context.Handler is IRequiresSessionState || app.Context.Handler is IReadOnlySessionState))
{
HttpCookie sessionTimeoutCookie = new HttpCookie(AspSessionAuditKey);
// check to see if there is a session cookie
string cookieHeader = app.Context.Request.Headers["Cookie"];
if ((null != cookieHeader) && (cookieHeader.IndexOf("ASP.NET_SessionId") >= 0) &&
!app.Context.Session.IsNewSession)
{
// session is live and this is a request so lets ensure the life span
app.Context.Session["__________SessionKicker"] = DateTime.Now;
sessionTimeoutCookie.Expires = DateTime.Now.AddMinutes(app.Session.Timeout).AddSeconds(2);
sessionTimeoutCookie.Value = MilliTimeStamp(sessionTimeoutCookie.Expires).ToString();
}
else
{
// session has timed out; don't fiddle with it
sessionTimeoutCookie.Expires = DateTime.Now.AddDays(-30);
sessionTimeoutCookie.Value = 0.ToString();
}
app.Response.Cookies.Add(sessionTimeoutCookie);
}
}
private static void HandleAuditRequest(object sender, EventArgs e)
{
HttpContext context = ((HttpApplication) sender).Context;
bool formsAudit = context.Request.Url.PathAndQuery.ToLower().StartsWith("/" + FormsAuthAuditKey);
bool aspSessionAudit = context.Request.Url.PathAndQuery.ToLower().StartsWith("/" + AspSessionAuditKey);
if (!formsAudit && !aspSessionAudit)
{
// your are not the droids i am looking for, you may move along...
return;
}
double timeout;
// want to know forms auth status
if (formsAudit)
{
HttpCookie formsAuthCookie = context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (formsAuthCookie != null)
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(formsAuthCookie.Value);
timeout = MilliTimeStamp(ticket.Expiration);
}
else
{
timeout = 0;
}
}
// want to know session status
else
{
// no session here, just take the word of SetAuditBugs
HttpCookie sessionTimeoutCookie = context.Request.Cookies[AspSessionAuditKey];
timeout = sessionTimeoutCookie == null ? 0 : Convert.ToDouble(sessionTimeoutCookie.Value);
}
// ensure that the response is not cached. That would defeat the whole purpose
context.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetNoStore();
// the money shot. a javascript date.
context.Response.Write(timeout.ToString());
context.Response.Flush();
context.Response.End();
}
/// <summary>
/// Found Code: http://forums.asp.net/t/1044408.aspx
/// </summary>
/// <param name="TheDate"></param>
/// <returns></returns>
private static double MilliTimeStamp(DateTime TheDate)
{
DateTime d1 = new DateTime(1970, 1, 1);
DateTime d2 = TheDate.ToUniversalTime();
TimeSpan ts = new TimeSpan(d2.Ticks - d1.Ticks);
return ts.TotalMilliseconds;
}
}
}
Клиентская библиотека
// <copyright project="AsynchronousSessionAuditor" file="AsynchronousSessionAuditor.js" company="Sky Sanders">
// This source is a Public Domain Dedication.
// http://spikes.codeplex.com
// Attribution is appreciated.
// </copyright>
var AsynchronousSessionAuditor = {
/// this script really should be served as a resource embedded in the assembly of the module
/// especially to keep the keys syncronized
pollingInterval: 60000, // 60 second polling. Not horrible, except for the server logs. ;)
formsAuthAuditKey: ".formsauthticket", // convenience members
aspSessionAuditKey: ".aspnetsession",
errorCallback: function(key, xhr) {
/// <summary>
/// Default behavior is to redirect to Default and provide the xhr error status text
/// in the loggedout query param.
///
/// You may replace this default behaviour with your own handler.
/// e.g. AsynchronousSessionAuditor.errorCallback = myMethod;
/// </summary>
/// <param name="key" type="String"></param>
/// <param name="xhr" type="XMLHttpRequest"></param>
window.location = "Default.aspx?loggedout=Error+" + xhr.statusText;
},
timeoutCallback: function(key, xhr) {
/// <summary>
/// Default behavior is to redirect to Default and provide the key value
/// in the loggedout query param.
///
/// You may replace this default behaviour with your own handler.
/// e.g. AsynchronousSessionAuditor.timeoutCallback= myMethod;
/// </summary>
/// <param name="key" type="String"></param>
/// <param name="xhr" type="XMLHttpRequest"></param>
window.location = "Default.aspx?loggedout=" + key;
// or just refresh. you will be sent to login.aspx
},
statusCallback: function(value) {
/// <summary>
/// Default behavior is to do nothing, which is not very interesting.
/// This value is set when AsynchronousSessionAuditor.init is called
/// </summary>
/// <param name="value" type="String">
/// The responseText of the audit request. Most certainly is a JavaScript Date
/// as a number. Just cast to date to get the requested expiration dateTime.
/// e.g. var exp = new Date(parseFloat(value)); if (isNaN(exp)){this should never happen}
/// </param>
window.location = "Default.aspx?loggedout=" + key;
// or just refresh. you will be sent to login.aspx
},
createXHR: function() {
/// <summary>
/// This xhr factory is not the best I have see.
/// You may wish to replace it with another or
/// use your favorite ajax library to make the
/// call.
/// </summary>
var xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
else {
throw new Error("Could not create XMLHttpRequest object.");
}
return xhr;
},
auditSession: function(key) {
/// <summary>
/// Make a request that will be serviced by the audit module to determine the
/// state of the current FormsAuthentication ticket or Asp.Net session
///
/// The return value is a JavaScript date, in numeric form, that represents the
/// expiration of the item specified by key.
/// Just cast it to date, i.e. new Date(parseFloat(xhr.resposeText))
/// </summary>
/// <param name="key" type="String">
/// the server key for the item to audit.
///
/// use ".formsauthticket" to get the expiration dateTime for the forms authentication
/// ticket, if any.
///
/// use ".aspnetsession" to get the expiration of the current ASP.Net session.
///
/// Both have convenience members on this object.
/// </param>
var xhr = AsynchronousSessionAuditor.createXHR();
xhr.open("GET", key, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status != 200) {
AsynchronousSessionAuditor.errorCallback(key, xhr);
}
else {
var timeout = parseFloat(xhr.responseText)
if (isNaN(timeout) || (new Date(timeout) < new Date())) {
AsynchronousSessionAuditor.timeoutCallback(key, xhr);
}
else {
AsynchronousSessionAuditor.statusCallback(xhr.responseText);
}
}
}
};
xhr.send(null);
},
init: function(key, statusCallback) {
// set the statusCallback member for reference.
AsynchronousSessionAuditor.statusCallback = statusCallback;
// check right now
AsynchronousSessionAuditor.auditSession(key);
// and recurring
window.setInterval((function() { AsynchronousSessionAuditor.auditSession(key) }), AsynchronousSessionAuditor.pollingInterval);
}
};
function callScriptMethod(url) {
/// <summary>
///
/// Simply makes a bogus ScriptService call to a void PageMethod name DoSomething simulating
/// an async (Ajax) call.
/// This resets the session cookie in the same way a postback or refresh would.
///
/// The same would apply to a ScriptService enabled XML Webservice call.
/// </summary>
var xhr = AsynchronousSessionAuditor.createXHR();
xhr.open("POST", url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status != 200) {
alert("script method call failed:" + xhr.statusText);
}
}
};
xhr.setRequestHeader("content-type", "application/json");
var postData = null;
xhr.send(postData);
}
Использование
<script src="AsynchronousSessionAuditor.js" type="text/javascript"></script>
<script type="text/javascript">
function reportStatus(value) {
/// <summary>
/// In a typical session/ticket lifetime you might display a warning at T-5 minutes that the session
/// is expiring and require an action.
/// </summary>
document.getElementById("sessionTimeout").innerHTML = "Session expires in " + parseInt((new Date(parseFloat(value)) - new Date())/1000) + " seconds.";
}
function init() {
// default is 60 seconds. Our session is only 1 minute so lets get crazy and poll every second
AsynchronousSessionAuditor.pollingInterval = 1000;
AsynchronousSessionAuditor.init(AsynchronousSessionAuditor.aspSessionAuditKey, reportStatus);
}
</script>
OH EM GEE Я искал что-то подобное в течение нескольких дней. Собираюсь попробовать завтра! :) – TheGeekYouNeed
@Cen, круто. не забудьте сообщить мне, как это работает. Я собираюсь выкопать его и использовать его через несколько дней. –
@SkySanders, я просто нашел это решение, спасибо! Мне потребовалось некоторое время, чтобы заставить его работать, но мне пришлось добавить «.formsauthticket» и «.aspnetsession» к сопоставлениям приложений в IIS, в частности, чтобы не проверять, существует ли файл. – chezy525
Другие ответы sugg показывая уведомление на странице, которая время от времени .. но я думаю, вы спрашиваете, как показать сообщение на странице, на которую перенаправляется пользователь.
Одна из возможностей заключается в том, чтобы просто передать параметр URL-адреса на стартовую страницу только по тайм-ауту сеанса. Затем ваш скрипт или код asp.net могут решить отобразить сообщение при наличии параметра.
вопрос был отредактирован mark. вы правы, это как раз то, на что похоже. Теперь. лол. –
- 1. Как продлить время сеанса, когда сеанс пуст в ASP.Net MVC?
- 2. Уничтожение сеанса пользователя в ASP.NET
- 3. Уведомлять пользователя, когда push-уведомления недоступны
- 4. Уведомлять пользователя, когда очередь удалена на rabbitmq
- 5. Время ожидания сеанса ASP.Net
- 6. Уведомлять приложение пользователя, когда транзакция завершена.
- 7. Необъяснимое время сеанса в ASP.NET
- 8. уведомлять клиента, когда время сеанса заканчивается во время ожидания обратного вызова из службы
- 9. Java - когда следует уведомлять или уведомлять?
- 10. Удержание пользователя во время сеанса
- 11. Время сеанса Asp.net слишком короткое
- 12. Аутентификация + Сохранение пользователя сеанса ASP.NET
- 13. ASP.NET Как динамически изменять время сеанса для текущего зарегистрированного пользователя?
- 14. Время ожидания сеанса ASP.NET 2.0
- 15. Аутентификация пользователя без состояния сеанса в ASP.NET
- 16. Когда сохраняется состояние сеанса ASP.NET
- 17. ASP.NET, как выйти из учетной записи пользователя во время сеанса, когда пароль сбрасывается/изменяется
- 18. Время окончания сеанса
- 19. Уведомлять, когда Bluetooth включен
- 20. Отключить пользователя при завершении сеанса ASP.NET MVC
- 21. Поведение сеанса сеанса ASP.NET
- 22. Неограниченное время сеанса пользователя на сервере Worklight
- 23. Как получить время выхода сеанса пользователя magento
- 24. отслеживать время сеанса пользователя с помощью Global.Asax?
- 25. Уведомлять пользователя о новых данных
- 26. Asp.net C#, получение сеанса пользователя Microsoft RDS
- 27. Дать запрос, чтобы убить время сеанса пользователя
- 28. Когда сеанс отменяется во время типичного сеанса?
- 29. Уведомлять пользователя в браузере близко только
- 30. Время ожидания сеанса ASP.NET слишком рано
Response.Write! Aaaaaaaahh !!! :) – markt
видa вонючий, Shawn. ; -p Механизм является искусственным и каким-то образом должен применяться на каждой конечной точке. И .. как вы узнаете «Если сеанс близок к тайм-ауту ...» на клиенте? [вставьте здесь много ответов]. Хорошо, но что, если пользователь обращается к другой странице сайта на другой вкладке или на странице, делает запрос Ajax удачным сеансом? Не помешивая, просто скажи ... –
О, я слышу тебя ... Но однажды он сказал в комментарии (кажется, сейчас уже нет), что у него уже был тайм-аут сеанса, и он просто хотел отобразить сообщение на начальную страницу, к которой он перенаправляет. Поэтому я предположил, что у него есть location.href где-то установлен, и просто показывал ему, как изменить эту часть, чтобы отобразить сообщение на стартовой странице. –