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



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



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



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

691   8  

8 ответов:

чтобы убедиться, что 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).

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

для .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. Это эффективно для того, чтобы браузер снова запрашивал ресурс, но на самом деле не предотвращает кэширование.

на последней ноте. Вы должны понимать, что ресурсы также могут быть кэшированы между сервером и клиентом. Провайдеры, прокси и другие сетевые устройства также кэшируют ресурсы, и они часто используют внутренние правила, не глядя на фактический ресурс. С этим ты ничего не можешь поделать. Хорошей новостью является то, что они обычно кэшируются для более коротких временных рамок, таких как секунды или минуты.

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

[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

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

    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.

здесь

для MVC6 ( 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());
    }

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

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

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

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

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

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

кэширование ответов в ASP.NET ядро-NoStore и расположение.Нет

Comments

    Ничего не найдено.