Вопрос по asp.net-mvc, jquery, c#, asp.net-mvc-3, .net – Запретить кэширование в ASP.NET MVC для определенных действий с использованием атрибута

177

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

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

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

Если вы предполагаете, что что-то кэшируется, я рекомендую вам ознакомиться с механизмами управления кэшем здесь:w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 user338195

Ваш Ответ

8   ответов
1

Output Caching in MVC

None", VaryByParam = "*")]

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

Смотрите другие комментарии (1, 2, 3) на многочисленные ответы, уже предлагающие использовать это. Ваша вторая строка неверна и приведет к проблемам с некоторыми браузерами.
292

что 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).

Насколько я понимаю (и я не эксперт по jQuery), кеш: false только делает привязку jQuery к строке запроса изменяющимся значением на "трюк"; браузер думать, что запрос для чего-то еще. Теоретически это означает, что браузер все равно будет кэшировать результаты, просто не будет использовать кэшированные результаты. На клиенте должно быть более эффективно отключать кэширование через заголовки ответов.
@ Fr & # xE9; d & # xE9; ric, раздел спецификации, на который вы указываете, говорит, что кэши не могут кэшировать контент без хранилища: & quot; без хранилища & quot; Директива response указывает, что кеш НЕ ДОЛЖЕН хранить какую-либо часть немедленного запроса или ответа.
Я попробовал все в вышеупомянутом решении, и это не работает для меня.
Я бы приветствовал включение такого атрибута в официальный пакет ASP.NET :-)
Работал только на уровне контроллера, а не на уровне действий.
0

Asp.Net MVC Core для предотвращения кеширования браузера (в том числеInternet Explorer 11) является:

[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]

как описано в документации Microsoft:

Кэширование ответов в ASP.NET Core - NoStore и Location.None

4

DNX), здесь нетSystem.Web.OutputCacheAttribute

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

Но у нас есть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());
    }
5

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

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : OutputCacheAttribute
{
    public NoCacheAttribute()
    {
        this.Duration = 0;
    }
}
По какой-то причине MVC 3 не позволяет просто установить длительность 0. Вы должны добавить эти аннотации ... спасибо за обходной путь!
Для полноты, минимальная и более подходящая директиваno-cache, который по-прежнему разрешает кэширование, но требует повторной проверки на сервере происхождения перед любым использованием. Чтобы избежать даже повторного проверки кэширования, вы должны добавитьno-store вместе сno-cache. (no-store одно только явно неправильно, потому что энергозависимые кэши могут кэшировать контент, помеченный какno-store.)
max-age=0 никогда не имел в виду «кэш отключен». Это означает только то, что содержание ответа должно рассматриваться немедленноstale, но кешу разрешено его кешировать. Браузеры должны проверять свежесть устаревшего кэшированного содержимого перед его использованием, но это не является обязательным, если только дополнительная директиваmust-revalidate указано.
235

чтобы предотвратить кеширование.

Для .net Framework:[OutputCache(NoStore = true, Duration = 0)]

Для .net Core:[ResponseCache(NoStore = true, Duration = 0)]

Имейте в виду, что невозможно заставить браузер отключить кэширование. Лучшее, что вы можете сделать, - это предложить предложения, которым будет следовать большинство браузеров, обычно в форме заголовков или метатегов. Этот атрибут декоратора отключит кэширование сервера, а также добавит этот заголовок:Cache-Control: public, no-store, max-age=0, Он не добавляет метатеги. При желании, они могут быть добавлены вручную в представлении.

Кроме того, JQuery и другие клиентские платформы будут пытаться обмануть браузер, чтобы он не использовал его кэшированную версию ресурса, добавляя в URL такие вещи, как отметка времени или GUID. Это эффективно, когда браузер снова запрашивает ресурс, но на самом деле не мешает кешированию.

На последнем замечании. Вы должны знать, что ресурсы могут также кэшироваться между сервером и клиентом. Интернет-провайдеры, прокси-серверы и другие сетевые устройства также кэшируют ресурсы, и они часто используют внутренние правила, не обращая внимания на реальный ресурс. Вы не можете ничего с этим поделать. Хорошей новостью является то, что они обычно кешируются на более короткие промежутки времени, например, секунды или минуты.

Для ядра ASP.NET используйте: «[ResponseCache (NoStore = true, Duration = 0)]»
Я могу понять, почему вы используетеNoStore = true а такжеDuration = 0 (что я успешно использовал, спасибо), но какой дополнительный эффект будетVaryByParam = "None" есть, как другие две опции влияют на все запросы независимо от параметра?
Я считаю, что это не в полной мере решить вопрос. Это отключает кэширование ASP.NET, но не кэширование в браузере.
Невозможно заставить браузер отключить кеширование. Лучшее, что вы можете сделать, - это предложить предложения, которым будет следовать большинство браузеров, обычно в форме заголовков или метатегов. Этот атрибут декоратора отключит кэширование сервера .NET, а также добавит заголовокCache-Control:public, no-store, max-age=0, Он не добавляет метатеги. При желании, они могут быть добавлены вручную в представлении.
Я не думаю, что это требуется в MVC, я просто был откровенен. Я помню, что в веб-формах и пользовательских элементах управления ASP.NET этот атрибут или атрибут VaryByControl являются обязательными.
13

    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.
47

[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

Это имеет несколько любопытное поведение настройкиCache-Control вpublic
IE8 по-прежнему отображает кэшированную версию страницы, когда нажимается обратная буфера, используя только Duration = 0 для действия контроллера. Использование NoStore = true вместе с Duration = 0 (см. Ответ Джареда) исправило поведение в моем случае.
max-age=0 никогда не имел в виду «кэш отключен». Это означает только то, что содержание ответа должно рассматриваться немедленноstale, но кешу разрешено его кешировать. Браузеры должны проверять свежесть устаревшего кэшированного содержимого перед его использованием, но это не является обязательным, если только дополнительная директиваmust-revalidate указано.

Похожие вопросы