2012-05-30 85 views
1

我在asp.mvc中註銷時遇到問題。 用戶可以按回來按鈕,他會看到上次訪問的頁面。ASP MVC 3註銷

我進行了一些搜索,發現類似這樣的解決方案:

this.Response.Cache.SetExpires(DateTime.UtcNow.AddYears(-1)); 
this.Response.Cache.SetCacheability(HttpCacheability.NoCache); 
this.Response.Cache.SetNoStore(); 

,但我應該把它添加到每個網頁,使其工作。

是否有某種方法可以禁用緩存,用於mvc應用程序中所有控制器的所有GET請求,然後爲其中一些例如屬性或自定義過濾器啓用它?

+0

他當然可以。他爲什麼不應該?但是,他不能執行任何操作。更改緩存設置僅影響當前頁面。 – jgauffin

回答

3

讓它在全球範圍內工作並不是太多工作。我過去所做的是創建一個派生自ActionFilter的類,然後將其作爲global.asax中的全局動作過濾器添加。另請注意,實際上強制所有瀏覽器重新加載並非微不足道。即使下面的代碼並不總是與Safari一起使用,Safari通常不得不通過空身體標籤或類似的onload來欺騙。

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Web.Mvc; 

/// <summary> 
/// Action filter that instructs the page to expire. 
/// </summary> 
public class PageExpirationAttribute : ActionFilterAttribute 
{ 
    /// <summary> 
    /// The OnActionExecuted method. 
    /// </summary> 
    /// <param name="filterContext">The current ActionExecutedContext. </param> 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     base.OnActionExecuting(filterContext); 

     filterContext.HttpContext.Response.ClearHeaders(); 
     filterContext.HttpContext.Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate, post-check=0, pre-check=0, max-age=0"); 
     filterContext.HttpContext.Response.AppendHeader("Pragma", "no-cache"); 
     filterContext.HttpContext.Response.AppendHeader("Keep-Alive", "timeout=3, max=993"); 
     filterContext.HttpContext.Response.AppendHeader("Expires", "Mon, 26 Jul 1997 05:00:00 GMT"); 
    } 
} 

如果您希望能夠排除某些頁面,則可以創建可應用於控制器或方法的另一個屬性。你OnActionExecuting()可以檢查是否存在該屬性:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
public sealed class AllowCachingAttribute : Attribute 
{ 
} 

近似代碼添加到OnActionExecuting

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Web.Mvc; 

/// <summary> 
/// Action filter that instructs the page to expire. 
/// </summary> 
public class PageExpirationAttribute : ActionFilterAttribute 
{ 
    /// <summary> 
    /// The OnActionExecuted method. 
    /// </summary> 
    /// <param name="filterContext">The current ActionExecutedContext. </param> 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     base.OnActionExecuting(filterContext); 

     bool skipCache = filterContext.ActionDescriptor.IsDefined(typeof(AllowCachingAttribute), true) 
       || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowCachingAttributee), true); 

     if (!skipCache) 
     { 

     filterContext.HttpContext.Response.ClearHeaders(); 
     filterContext.HttpContext.Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate, post-check=0, pre-check=0, max-age=0"); 
     filterContext.HttpContext.Response.AppendHeader("Pragma", "no-cache"); 
     filterContext.HttpContext.Response.AppendHeader("Keep-Alive", "timeout=3, max=993"); 
     filterContext.HttpContext.Response.AppendHeader("Expires", "Mon, 26 Jul 1997 05:00:00 GMT"); 
     } 
    } 
} 
+0

謝謝!這對我來說非常合適!這正是我正在尋找的! –

0

您可以創建一個實用程序類並添加一個公共靜態方法,執行上述代碼然後調用它。然後在您的Methods的控制器中調用Utilities方法。我將提供一些代碼:

namespace App 
{ 
    public class Utility 
    { 
     public static void SetResponsAttributes(HttpResponseBase theResponseObject) 
     { 
      if (theResponseObject == null) return; 

      theResponseObject.Cache.SetExpires(DateTime.UtcNow.AddYears(-1)); 
      theResponseObject.Cache.SetCacheability(HttpCacheability.NoCache); 
      theResponseObject.Cache.SetNoStore(); 
     } 
    } 
} 
+0

是的,但我不想在每個控制器的每個動作中調用此方法。我正在尋找一些方法來默認添加這個,然後刪除我想要的地方。 –

+0

Gotcha .....我嘗試了global.asax.cs但是在這種情況下Response不可用。讓我們來看看我們還能做些什麼 – MikeTWebb

0

爲什麼不設置會話標誌來指示已登錄的指示器並將整個視圖內容包裝在if塊內。在註銷時放棄會話。

+0

這是行不通的,因爲瀏覽器會從緩存中加載最後一頁。它甚至不向服務器提交任何渲染頁面的請求。我正在使用FormsAuthentication.SignOut();和Session.Abandon();但它不會阻止用戶使用「返回」按鈕返回到最後一頁。 –