Предотrotation кэширования в ASP.NET MVC для определенных действий с использованием атрибута
У меня есть приложение ASP.NET MVC 3. Это приложение запрашивает записи через JQuery. JQuery обращается к действию controllerа, которое возвращает результаты в формате JSON. Я не смог это доказать, но я обеспокоен тем, что мои данные могут кэшироваться.
Я хочу, чтобы кеширование было применено к определенным действиям, а не ко всем действиям.
Есть ли атрибут, который я могу применить к действию, чтобы гарантировать, что данные не будут кэшироваться? Если нет, как я могу гарантировать, что браузер получает новый набор записей каждый раз, а не кешированный набор?
- Как выбрать конкретный элемент формы в jQuery?
- jQuery Таблицы данных: ширина таблицы управления
- jquery datetime picker set minDate dynamic
- Изменение флажка jQuery и событие click
- Jquery Ajax Загрузка изображения
- проверка на стороне клиента в атрибуте пользовательской проверки - asp.net mvc 4
- полный календарный выбор ячейки на мобильном устройстве?
- Ошибка: нечистить SyntaxError: Неожиданный токен <
- Twitter Bootstrap Datepicker в модальном окне
- jQuery - форма подачи резюме после вызова ajax
- jQuery Ajax дождитесь загрузки всех изображений
- Как использовать событие jQuery для выгрузки файлов, загруженных с рабочего стола?
- Как добавить функцию в jQuery?
Чтобы гарантировать, что 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); } }
Затем просто украсьте свой controller с помощью [NoCache]
. ИЛИ сделать это за все, что вы могли бы просто поместить атрибут в class базового classа, который вы наследуете от своих controllerов (если он у вас есть), как у нас здесь:
[NoCache] public class ControllerBase : Controller, IControllerBase
Вы также можете украсить некоторые действия этим атрибутом, если вам нужно, чтобы они были не кешируемыми, а не украшали весь controller.
Если у вашего classа или действия не было NoCache
когда оно было отображено в вашем браузере, и вы хотите проверить его работоспособность, помните, что после компиляции изменений вам нужно выполнить «жесткое обновление» (Ctrl + F5) в вашем браузере. Пока вы это сделаете, ваш браузер сохранит старую кешированную версию и не обновит ее с помощью «обычного обновления» (F5).
Вы можете использовать встроенный атрибут кеша, чтобы предотвратить кеширование.
Для .net Framework: [OutputCache(NoStore = true, Duration = 0)]
Для ядра .net: [ResponseCache(NoStore = true, Duration = 0)]
Имейте в виду, что невозможно заставить браузер отключить кеширование. Лучшее, что вы можете сделать, это предоставить рекомендации, которые будут выполняться большинством браузеров, обычно в виде заголовков или метатегов. Этот атрибут decorator отключит кеширование сервера, а также добавит этот заголовок: Cache-Control: public, no-store, max-age=0
. Он не добавляет метаtags. При желании они могут быть добавлены вручную в виде.
Кроме того, JQuery и другие клиентские среды попытаются обмануть браузер, не используя его кэшированную версию ресурса, добавив материал в URL-адрес, например, метку времени или GUID. Это эффективно, когда браузер снова запрашивает ресурс, но на самом деле не предотвращает кеширование.
В заключение. Вы должны знать, что ресурсы также могут быть кэшированы между сервером и клиентом. Провайдеры, прокси-серверы и другие сетевые устройства также кэшируют ресурсы, и они часто используют внутренние правила, не глядя на фактический ресурс. Это не так много. Хорошей новостью является то, что они обычно кэшируют более короткие временные frameworks, например, секунды или минуты.
Все что тебе нужно это:
[OutputCache(Duration=0)] public JsonResult MyAction(
или, если вы хотите отключить его для всего controllerа:
[OutputCache(Duration=0)] public class MyController
Несмотря на дискуссию в комментариях здесь, этого достаточно, чтобы отключить кеширование браузера – это заставляет ASP.Net выпускать заголовки ответов, которые сообщают браузеру об истечении срока действия документа:
В действии controllerа добавьте в заголовок следующие строки
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.
Вот атрибут NoCache, предложенный mattytommo, упрощенный, используя информацию из ответа Криса Москини:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public sealed class NoCacheAttribute : OutputCacheAttribute { public NoCacheAttribute() { this.Duration = 0; } }
Для MVC6 ( DNX ) нет System.Web.OutputCacheAttribute
Примечание: при установке параметра 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()); }
Кэширование вывода в MVC
[OutputCache (NoStore = true, Duration = 0, Location = "None", VaryByParam = "*")] ИЛИ [OutputCache (NoStore = true, Duration = 0, VaryByParam = "None")]
Правильное значение атрибута для Asp.Net MVC Core для предотвращения кеширования браузера (включая Internet Explorer 11 ):
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
как описано в документации Microsoft:
Кэширование ответов в ASP.NET Core – NoStore и Location.None