c# - framework - asp.net mvc 6



在ASP.NET MVC中阻止使用屬性進行特定操作的緩存 (6)

我有一個ASP.NET MVC 3應用程序。 此應用程序通過JQuery請求記錄。 JQuery返回一個以JSON格式返回結果的控制器動作。 我無法證明這一點,但我擔心我的數據可能會被緩存。

我只希望將緩存應用於特定的操作,而不是針對所有操作。

是否有一個屬性可以讓我確保數據不會被緩存? 如果不是,我如何確保瀏覽器每次都得到一組新記錄,而不是緩存集?

https://ffff65535.com


MVC中的輸出緩存

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

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


下面是Mattytommo提出的NoCache屬性,通過使用Chris Moschini的答案中的信息進行簡化:

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

您可以使用內置的緩存屬性來防止緩存。

對於.net框架: [OutputCache(NoStore = true, Duration = 0)]

對於.net核心: [ResponseCache(NoStore = true, Duration = 0)]

請注意,強制瀏覽器禁用緩存是不可能的。 您所能做的最好的是提供大多數瀏覽器會提供的建議,通常以標頭或元標記的形式提供。 此decorator屬性將禁用服務器緩存,並添加以下標頭: Cache-Control: public, no-store, max-age=0 。 它不會添加元標記。 如果需要,可以在視圖中手動添加。

此外,JQuery和其他客戶端框架將嘗試通過向URL添加內容來誘使瀏覽器不使用它的緩存版本的資源,如時間戳或GUID。 這在使瀏覽器再次請求資源時非常有效,但並不能真正阻止緩存。

在最後的筆記。 您應該知道資源也可以緩存在服務器和客戶端之間。 ISP的代理和其他網絡設備也會緩存資源,並且他們通常使用內部規則而不查看實際資源。 關於這些你可以做的事情不多。 好消息是,它們通常緩存較短的時間幀,如秒或分鐘。


為了確保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-3