c# - idistributedcache - Impedir o cache no ASP.NET MVC para ações específicas usando um atributo




cache.net core api (6)

Eu tenho um aplicativo ASP.NET MVC 3. Este aplicativo solicita registros por meio do JQuery. O JQuery chama de volta a uma ação do controlador que retorna resultados no formato JSON. Não consegui provar isso, mas estou preocupado com o fato de meus dados estarem sendo armazenados em cache.

Eu só quero que o cache seja aplicado a ações específicas, não a todas as ações.

Existe um atributo que eu possa colocar em uma ação para garantir que os dados não sejam armazenados em cache? Se não, como posso garantir que o navegador receba um novo conjunto de registros a cada vez, em vez de um conjunto em cache?


Aqui está o atributo NoCache proposto pelo mattytommo, simplificado usando as informações da resposta de Chris Moschini:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : OutputCacheAttribute
{
    public NoCacheAttribute()
    {
        this.Duration = 0;
    }
}

Corrigir o valor do atributo para o Asp.Net MVC Core para impedir que o cache do navegador (incluindo o Internet Explorer 11 ) seja:

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

conforme descrito na documentação da Microsoft:

Cache de Resposta no ASP.NET Core - NoStore e Location.None


Para MVC6 ( DNX ), não há System.Web.OutputCacheAttribute

Nota: quando você define o parâmetro NoStore Duration, não é considerado. É possível definir uma duração inicial para o primeiro registro e substituir isso por atributos personalizados.

Mas nós temos o Microsoft.AspNet.Mvc.Filters.ResponseCacheFilter

 public void ConfigureServices(IServiceCollection services)
        ...
        services.AddMvc(config=>
        {
            config.Filters.Add(
                 new ResponseCacheFilter(
                    new CacheProfile() { 
                      NoStore=true
                     }));
        }
        ...
       )

É possível substituir o filtro inicial por um atributo personalizado

    [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);
        }
    }

Aqui está um caso de uso

    [NoCache]
    [HttpGet]
    public JsonResult Get()
    {            
        return Json(new DateTime());
    }

Para garantir que o JQuery não esteja armazenando os resultados em cache nos seus métodos ajax, coloque o seguinte:

$.ajax({
    cache: false
    //rest of your ajax setup
});

Ou para evitar o cache no MVC, criamos nosso próprio atributo, você poderia fazer o mesmo. Aqui está nosso código:

[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);
    }
}

Então apenas decore seu controlador com [NoCache] . OU para fazer isso, basta colocar o atributo na classe da classe base da qual você herdou seus controllers (se você tiver um) como temos aqui:

[NoCache]
public class ControllerBase : Controller, IControllerBase

Você também pode decorar algumas das ações com esse atributo se precisar que elas não sejam armazenáveis ​​em cache, em vez de decorar o controlador inteiro.

Se a sua classe ou ação não tiver NoCache quando foi renderizada no seu navegador e você quiser verificar se está funcionando, lembre-se de que, depois de compilar as mudanças, você precisa fazer uma "hard refresh" (Ctrl + F5) no seu navegador. Até que você faça isso, seu navegador manterá a versão antiga em cache e não a atualizará com uma "atualização normal" (F5).


Você pode usar o atributo de cache interno para impedir o armazenamento em cache.

Para o .NET Framework: [OutputCache(NoStore = true, Duration = 0)]

Para núcleo .net: [ResponseCache(NoStore = true, Duration = 0)]

Esteja ciente de que é impossível forçar o navegador a desativar o armazenamento em cache. O melhor que você pode fazer é fornecer sugestões que a maioria dos navegadores honrará, geralmente na forma de cabeçalhos ou metatags. Este atributo decorator desabilitará o cache do servidor e também adicionará este cabeçalho: Cache-Control: public, no-store, max-age=0 . Não adiciona meta tags. Se desejado, esses podem ser adicionados manualmente na exibição.

Além disso, o JQuery e outras estruturas de cliente tentarão enganar o navegador para não usar a versão em cache de um recurso, adicionando informações ao URL, como um registro de data e hora ou GUID. Isso é eficaz para fazer o navegador solicitar o recurso novamente, mas não impede o armazenamento em cache.

Em uma nota final. Você deve estar ciente de que os recursos também podem ser armazenados em cache entre o servidor e o cliente. ISPs, proxies e outros dispositivos de rede também armazenam recursos em cache e geralmente usam regras internas sem examinar o recurso real. Não há muito o que fazer sobre isso. A boa notícia é que eles normalmente armazenam em cache por períodos de tempo mais curtos, como segundos ou minutos.


Cache de Saída no MVC

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

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





asp.net-mvc-3