Вопрос по asp.net-mvc, jquery, c#, asp.net-mvc-3, .net – Запретить кэширование в ASP.NET MVC для определенных действий с использованием атрибута
У меня есть приложение ASP.NET MVC 3. Это приложение запрашивает записи через JQuery. JQuery вызывает действие контроллера, которое возвращает результаты в формате JSON. Я не смог доказать это, но я обеспокоен тем, что мои данные могут кэшироваться.
Я хочу, чтобы кэширование применялось только к конкретным действиям, а не ко всем действиям.
Есть ли атрибут, который я могу добавить к действию, чтобы гарантировать, что данные не кэшируются? Если нет, как я могу гарантировать, что браузер каждый раз получает новый набор записей вместо кэшированного набора?
что 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).
Asp.Net MVC Core для предотвращения кеширования браузера (в том числеInternet Explorer 11) является:
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
как описано в документации Microsoft:
Кэширование ответов в ASP.NET Core - NoStore и Location.None
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());
}
NoCache
атрибут, предложенный mattytommo, упрощен с использованием информации из ответа Криса Москини:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : OutputCacheAttribute
{
public NoCacheAttribute()
{
this.Duration = 0;
}
}
no-cache
, который по-прежнему разрешает кэширование, но требует повторной проверки на сервере происхождения перед любым использованием. Чтобы избежать даже повторного проверки кэширования, вы должны добавитьno-store
вместе сno-cache
. (no-store
одно только явно неправильно, потому что энергозависимые кэши могут кэшировать контент, помеченный какno-store
.)
max-age=0
никогда не имел в виду «кэш отключен». Это означает только то, что содержание ответа должно рассматриваться немедленноstale, но кешу разрешено его кешировать. Браузеры должны проверять свежесть устаревшего кэшированного содержимого перед его использованием, но это не является обязательным, если только дополнительная директиваmust-revalidate
указано.
чтобы предотвратить кеширование.
Для .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. Это эффективно, когда браузер снова запрашивает ресурс, но на самом деле не мешает кешированию.
На последнем замечании. Вы должны знать, что ресурсы могут также кэшироваться между сервером и клиентом. Интернет-провайдеры, прокси-серверы и другие сетевые устройства также кэшируют ресурсы, и они часто используют внутренние правила, не обращая внимания на реальный ресурс. Вы не можете ничего с этим поделать. Хорошей новостью является то, что они обычно кешируются на более короткие промежутки времени, например, секунды или минуты.
NoStore = true
а такжеDuration = 0
(что я успешно использовал, спасибо), но какой дополнительный эффект будетVaryByParam = "None"
есть, как другие две опции влияют на все запросы независимо от параметра?
Cache-Control:public, no-store, max-age=0
, Он не добавляет метатеги. При желании, они могут быть добавлены вручную в представлении.
[OutputCache(Duration=0)]
public JsonResult MyAction(
или, если вы хотите отключить его для всего контроллера:
[OutputCache(Duration=0)]
public class MyController
Несмотря на обсуждение в комментариях здесь, этого достаточно, чтобы отключить кэширование браузера - это заставляет ASP.Net выдавать заголовки ответа, которые сообщают браузеру, что срок действия документа истекает немедленно:
Cache-Control
вpublic
max-age=0
никогда не имел в виду «кэш отключен». Это означает только то, что содержание ответа должно рассматриваться немедленноstale, но кешу разрешено его кешировать. Браузеры должны проверять свежесть устаревшего кэшированного содержимого перед его использованием, но это не является обязательным, если только дополнительная директиваmust-revalidate
указано.