[英]Prevent Caching in ASP.NET MVC for specific actions using an attribute
我有一個 ASP.NET MVC 3 應用程序。 此應用程序通過 jQuery 請求記錄。jQuery 回調 controller 操作,以 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]
裝飾你的 controller 。 或者為所有人做這件事,你可以把屬性放在基 class 的 class 上,你從那里繼承你的控制器(如果你有一個)就像我們在這里:
[NoCache]
public class ControllerBase : Controller, IControllerBase
如果你需要它們是不可緩存的,你也可以用這個屬性裝飾一些動作,而不是裝飾整個 controller。
如果您的 class 或操作在您的瀏覽器中呈現時沒有NoCache
,並且您想檢查它是否正常工作,請記住在編譯更改后您需要在瀏覽器中執行“硬刷新”(Ctrl+F5)。 在您這樣做之前,您的瀏覽器將保留舊的緩存版本,並且不會使用“正常刷新”(F5) 對其進行刷新。
您可以使用內置的緩存屬性來防止緩存。
對於 .net 框架: [OutputCache(NoStore = true, Duration = 0)]
對於 .net 核心: [ResponseCache(NoStore = true, Duration = 0)]
請注意,無法強制瀏覽器禁用緩存。 您能做的最好的事情就是提供大多數瀏覽器都會接受的建議,通常以標題或元標記的形式。 此裝飾器屬性將禁用服務器緩存並添加此 header: Cache-Control: public, no-store, max-age=0
。 它不添加元標記。 如果需要,可以在視圖中手動添加這些。
此外,JQuery 和其他客戶端框架將嘗試通過向 url 添加內容(如時間戳或 GUID)來誘使瀏覽器不使用其緩存的資源版本。 這可以有效地讓瀏覽器再次請求資源,但並不能真正阻止緩存。
最后一點。 您應該知道資源也可以緩存在服務器和客戶端之間。 ISP、代理和其他網絡設備也緩存資源,它們通常使用內部規則而不查看實際資源。 您對此無能為力。 好消息是它們通常緩存較短的時間范圍,例如幾秒或幾分鍾。
所有你需要的是:
[OutputCache(Duration=0)]
public JsonResult MyAction(
或者,如果您想為整個 Controller 禁用它:
[OutputCache(Duration=0)]
public class MyController
盡管這里的評論存在爭議,但這足以禁用瀏覽器緩存——這會導致 ASP.Net 發出響應標頭,告訴瀏覽器文檔立即過期:
在controller動作append到header下面幾行
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.
這是 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());
}
ASP.NET MVC 5 解決方案:
App_Start/FilterConfig.cs
的RegisterGlobalFilters
方法: public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
// ...
filters.Add(new OutputCacheAttribute
{
NoStore = true,
Duration = 0,
VaryByParam = "*",
Location = System.Web.UI.OutputCacheLocation.None
});
}
}
Controller
或View
級別應用不同的OutputCache
指令來覆蓋全局過濾器。 對於常規 Controller 它是[OutputCache(NoStore = true, Duration = 0, Location=System.Web.UI.ResponseCacheLocation.None, VaryByParam = "*")]
或者如果它是一個ApiController
它會是
[System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, Location = System.Web.UI.OutputCacheLocation.None, VaryByParam = "*")]
Asp.Net MVC Core防止瀏覽器緩存(包括Inte.net Explorer 11 )的正確屬性值為:
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
如 Microsoft 文檔中所述:
Output MVC 中的緩存
[OutputCache(NoStore = true, Duration = 0, Location="None", VaryByParam = "*")] OR [OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.