Предотвращение кэширования в 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 выпускать заголовки ответов, которые сообщают браузеру, что документ истекает немедленно:
Ответ 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")]