0

我正試圖跟蹤會話過期,並且當應用程序在我的開發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 
{ 
} 
+1

我會猜測你在本地使用Visual Studio開發服務器,在服務器上使用IIS。我猜測這種會話使用模式取決於事件的流水線順序,而當IIS執行此操作時會話不存在,因爲默認情況下IIS處於集成模式。嘗試更改爲Classic,或更改使用Session的方式,以便它與Integrated一起使用。 – MatthewMartin 2014-11-06 20:52:09

+0

另外,我認爲有人下了選票,因爲這個問題有點太多了。 – MatthewMartin 2014-11-06 20:52:43

+0

是的,我在本地運行VS 2013 dev服務器。 「會話尚未存在」是什麼意思?應用程序運行順利,直到會話過期。此外,當我設置非常短的會話超時(如1或2)時,它在服務器上正常運行。但是,如果我離開網頁超過30分鐘,操作屬性不再觸發。 – ecasper 2014-11-06 22:19:20

回答

1

最後我發現不當行爲的原因。

我的操作過濾器不作爲IIS>應用程序池>高級設置>空閒超時(分鐘)設置觸發我的會話狀態之前達到超時。默認值爲20.

將該值設置爲0將禁用IIS idel超時。

0

它會給出錯誤

錯誤:無效的會話超時參數值。輸入一個正整數小於或等於500000

你可以嘗試

if ((Session["project"] == null) && (Session["User"] == null) && (Label1.Text == "Label") && (Label2.Text == "Label")) 

    { 
     Session.Abandon(); 
     Response.Redirect("Default.aspx"); 
    } 

    else 
    { 

     if ((Session["User"] == null) || (Session["project"] == null)) 

     { 
      Session["project"] = Label1.Text; 
      Session["User"] = Label2.Text; 
     } 

     if ((Label1.Text == "Label") || (Label2.Text == "Label")) 

     { 
      Label1.Text = Session["project"].ToString(); 
      Label2.Text = Session["User"].ToString(); 
     } 

    } 

,讓你認證方式爲None而不是窗口從IIS> Asp.net設置>身份驗證模式

相關問題