2012-05-30 3 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(); 

, но я должен добавить его к каждой странице, чтобы сделать его работу.

Есть ли способ отключить кеш для всех запросов GET для всех контроллеров в приложении mvc, а затем включить его для некоторых из них, например, с атрибутом или настраиваемым фильтром?

+0

Конечно, он может. Почему он не должен? Однако он не может выполнять никаких действий. Изменение настроек кеша влияет только на текущую страницу. – jgauffin

ответ

3

Это не так много работы, чтобы заставить его работать в глобальном масштабе. Мы в прошлом создали класс, который происходит из ActionFilter, а затем добавим его как глобальный фильтр действий в global.asax. Также обратите внимание, что фактически принудительное перезагрузка всех браузеров не является тривиальной. Даже приведенный ниже код не всегда работает с Safari, который часто приходится обманывать пустым загрузочным тегом тела или аналогичным.

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

Вы можете создать класс Утилиты и добавить открытый статический метод, который выполняет вышеуказанный код, а затем вызывает его. Затем в «Методах ваших контроллеров» вызовите метод «Утилиты». Я предоставлю некоторый код:

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 Но ответ не доступен в этом контексте. Давайте посмотрим, что еще мы можем сделать – MikeTWebb

0

Почему бы не установить флаг сеанса, чтобы указать индикатор входа в систему и обернуть содержимое всего представления внутри блока if. Отказаться от сеанса при выходе из системы.

+0

, это не сработает, потому что браузер загружает последнюю страницу из кеша. Он даже не делает никаких запросов на сервер для отображения страницы. Я использую FormsAuthentication.SignOut(); и Session.Abandon(); но это не мешает пользователю вернуться на последнюю страницу с помощью кнопки «Назад». –

Смежные вопросы