Предотвращение кэширования в ASP.NET MVC для определенных действий с использованием атрибута

У меня есть приложение ASP.NET MVC 3. Это приложение запрашивает записи через JQuery. JQuery обращается к действию контроллера, которое возвращает результаты в формате JSON. Я не смог это доказать, но я обеспокоен тем, что мои данные могут кэшироваться.

Я хочу, чтобы кеширование было применено к определенным действиям, а не для всех действий.

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

Ответ 1

Чтобы гарантировать, что JQuery не кэширует результаты, по вашим методам ajax, поставьте следующее:

$.ajax({
    cache: false
    //rest of your ajax setup
});

Или для предотвращения кэширования в MVC мы создали собственный атрибут, вы можете сделать то же самое. Здесь наш код:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
        filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext.HttpContext.Response.Cache.SetNoStore();

        base.OnResultExecuting(filterContext);
    }
}

Затем просто украсьте ваш контроллер с помощью [NoCache]. ИЛИ сделать это за все, что вы могли бы просто поместить атрибут в класс базового класса, который вы наследуете от своих контроллеров (если он у вас есть), как у нас:

[NoCache]
public class ControllerBase : Controller, IControllerBase

Вы также можете украсить некоторые действия этим атрибутом, если вам нужно, чтобы они были не кешируемыми, а не украшали весь контроллер.

Если у вашего класса или действия не было NoCache, когда оно было отображено в вашем браузере, и вы хотите проверить его работоспособность, помните, что после компиляции изменений вам нужно выполнить "жесткое обновление" (Ctrl + F5) в вашем браузере. Пока вы это сделаете, ваш браузер сохранит старую кешированную версию и не обновит ее с помощью "обычного обновления" (F5).

Ответ 2

Вы можете использовать встроенный атрибут кеша, чтобы предотвратить кеширование. Для использования .net 4.x:

[OutputCache(NoStore = true, Duration = 0)]

Для использования ядра .net:

[ResponseCache(NoStore = true, Duration = 0)]

Ответ 3

Все, что вам нужно, это:

[OutputCache(Duration=0)]
public JsonResult MyAction(

или, если вы хотите отключить его для всего контроллера:

[OutputCache(Duration=0)]
public class MyController

Несмотря на дискуссию в комментариях здесь, этого достаточно, чтобы отключить кеширование браузера - это заставляет ASP.Net выпускать заголовки ответов, которые сообщают браузеру, что документ истекает немедленно:

OutputCache Duration=0 Response Headers: max-age=0, s-maxage=0

Ответ 4

В действии контроллера добавьте в заголовок следующие строки

    public ActionResult Create(string PositionID)
    {
        Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
        Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
        Response.AppendHeader("Expires", "0"); // Proxies.

Ответ 5

Здесь атрибут NoCache, предложенный mattytommo, упрощенный с помощью информации от Криса Москини:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : OutputCacheAttribute
{
    public NoCacheAttribute()
    {
        this.Duration = 0;
    }
}

Ответ 6

Для MVC6 (DNX) нет System.Web.OutputCacheAttirbute

Примечание: при установке параметра NoStore Duration не учитывается. Можно установить начальную продолжительность для первой регистрации и переопределить это с помощью настраиваемых атрибутов.

Но имеем Microsoft.AspNet.Mvc.Filters.ResponseCacheFilter

 public void ConfigureServices(IServiceCollection services)
        ...
        services.AddMvc(config=>
        {
            config.Filters.Add(
                 new ResponseCacheFilter(
                    new CacheProfile() { 
                      NoStore=true
                     }));
        }
        ...
       )

Можно переопределить начальный фильтр с помощью настраиваемого атрибута

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class NoCacheAttribute : ActionFilterAttribute
    {
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            var filter=filterContext.Filters.Where(t => t.GetType() == typeof(ResponseCacheFilter)).FirstOrDefault();
            if (filter != null)
            {
                ResponseCacheFilter f = (ResponseCacheFilter)filter;
                f.NoStore = true;
                //f.Duration = 0;
            }

            base.OnResultExecuting(filterContext);
        }
    }

Вот пример использования

    [NoCache]
    [HttpGet]
    public JsonResult Get()
    {            
        return Json(new DateTime());
    }

Ответ 7

Кэширование вывода в MVC

[OutputCache(NoStore = true, Duration = 0, Location="None", VaryByParam = "*")]

OR
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]