我正試圖跟蹤會話過期,並且當應用程序在我的開發PC上運行時,一切工作正常。但它不像預期的那樣在活動服務器上工作。我已經重新啓動服務器,但沒有運氣!我在Windows Server 2012(Windows Azure虛擬機)和IIS 8上運行。會話過期屬性不會被觸發在服務器上
我收到基於其操作被觸發的控制器的類似錯誤。由於控制器初始化失敗,因爲會話過期時會話變量_connectionstring爲空,所以會生成錯誤。
如果我將sessionState更改爲1,並將超時值設置爲2,然後重定向在服務器和開發環境中都完美工作。奇怪!!
我的問題是爲什麼動作過濾器錯過了在現場服務器環境中的行爲?它在開發環境下完美無瑕。我在這裏錯過了什麼?
以下是我的代碼。
的Web.Config:
<system.web>
<sessionState mode="InProc" timeout="20" />
<authentication mode="Forms">
<forms loginUrl="~/Auth/Login" timeout="25" slidingExpiration="true" />
</authentication>
</system.web>
過濾配置:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new SessionExpireFilterAttribute());
filters.Add(new LocsAuthorizeAttribute());
}
}
過濾器:
public class SessionExpireFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.ActionDescriptor.GetCustomAttributes(typeof(SkipActionFilterAttribute), false).Any())
{
return;
}
HttpContextBase ctx = filterContext.HttpContext;
//HttpContext ctx = HttpContext.Current;
// check if session is supported
if (ctx.Session != null)
{
// check if a new session id was generated
if (ctx.Session.IsNewSession)
{
// If it says it is a new session, but an existing cookie exists, then it must
// have timed out
string sessionCookie = ctx.Request.Headers["Cookie"];
if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0))
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
// For AJAX requests, we're overriding the returned JSON result with a simple string,
// indicating to the calling JavaScript code that a redirect should be performed.
filterContext.Result = new JsonResult { Data = "_Logon_" };
}
else
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary {
{ "action", "SessionTimeout" },
{ "controller", "Session" }});
}
}
}
}
base.OnActionExecuting(filterContext);
}
}
//[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class LocsAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.ActionDescriptor.GetCustomAttributes(typeof(SkipActionFilterAttribute), false).Any())
{
return;
}
HttpContext ctx = HttpContext.Current;
// If the browser session has expired...
if (ctx.Session["UserName"] == null)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
// For AJAX requests, we're overriding the returned JSON result with a simple string,
// indicating to the calling JavaScript code that a redirect should be performed.
filterContext.Result = new JsonResult { Data = "_Logon_" };
}
else
{
// For round-trip posts, we're forcing a redirect to Home/TimeoutRedirect/, which
// simply displays a temporary 5 second notification that they have timed out, and
// will, in turn, redirect to the logon page.
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary {
{ "action", "SessionTimeout" },
{ "controller", "Session" }});
}
}
else if (filterContext.HttpContext.Request.IsAuthenticated)
{
// Otherwise the reason we got here was because the user didn't have access rights to the
// operation, and a 403 should be returned.
filterContext.Result = new HttpStatusCodeResult(403);
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
}
public class SkipActionFilterAttribute : Attribute
{
}
我會猜測你在本地使用Visual Studio開發服務器,在服務器上使用IIS。我猜測這種會話使用模式取決於事件的流水線順序,而當IIS執行此操作時會話不存在,因爲默認情況下IIS處於集成模式。嘗試更改爲Classic,或更改使用Session的方式,以便它與Integrated一起使用。 – MatthewMartin 2014-11-06 20:52:09
另外,我認爲有人下了選票,因爲這個問題有點太多了。 – MatthewMartin 2014-11-06 20:52:43
是的,我在本地運行VS 2013 dev服務器。 「會話尚未存在」是什麼意思?應用程序運行順利,直到會話過期。此外,當我設置非常短的會話超時(如1或2)時,它在服務器上正常運行。但是,如果我離開網頁超過30分鐘,操作屬性不再觸發。 – ecasper 2014-11-06 22:19:20