可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have an ASP.NET MVC 3 application. This application requests records through JQuery. JQuery calls back to a controller action that returns results in JSON format. I have not been able to prove this, but I\'m concerned that my data may be getting cached.
I only want the caching to be applied to specific actions, not for all actions.
Is there an attribute that I can put on an action to ensure that the data does not get cached? If not, how do I ensure that the browser gets a new set of records each time, instead of a cached set?
回答1:
To ensure that JQuery isn\'t caching the results, on your ajax methods, put the following:
$.ajax({
cache: false
//rest of your ajax setup
});
Or to prevent caching in MVC, we created our own attribute, you could do the same. Here\'s our code:
[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);
}
}
Then just decorate your controller with [NoCache]
. OR to do it for all you could just put the attribute on the class of the base class that you inherit your controllers from (if you have one) like we have here:
[NoCache]
public class ControllerBase : Controller, IControllerBase
You can also decorate some of the actions with this attribute if you need them to be non-cacheable, instead of decorating the whole controller.
If your class or action didn\'t have NoCache
when it was rendered in your browser and you want to check it\'s working, remember that after compiling the changes you need to do a \"hard refresh\" (Ctrl+F5) in your browser. Until you do so, your browser will keep the old cached version, and won\'t refresh it with a \"normal refresh\" (F5).
回答2:
You can use the built in cache attribute to prevent caching.
For .net Framework: [OutputCache(NoStore = true, Duration = 0)]
For .net Core: [ResponseCache(NoStore = true, Duration = 0)]
Be aware that it is impossible to force the browser to disable caching. The best you can do is provide suggestions that most browsers will honor, usually in the form of headers or meta tags. This decorator attribute will disable server caching and also add this header: Cache-Control: public, no-store, max-age=0
. It does not add meta tags. If desired, those can be added manually in the view.
Additionally, JQuery and other client frameworks will attempt to trick the browser into not using it\'s cached version of a resource by adding stuff to the url, like a timestamp or GUID. This is effective in making the browser ask for the resource again but doesn\'t really prevent caching.
On a final note. You should be aware that resources can also be cached in between the server and client. ISP\'s, proxies, and other network devices also cache resources and they often use internal rules without looking at the actual resource. There isn\'t much you can do about these. The good news is that they typically cache for shorter time frames, like seconds or minutes.
回答3:
All you need is:
[OutputCache(Duration=0)]
public JsonResult MyAction(
or, if you want to disable it for an entire Controller:
[OutputCache(Duration=0)]
public class MyController
Despite the debate in comments here, this is enough to disable browser caching - this causes ASP.Net to emit response headers that tell the browser the document expires immediately:
回答4:
In the controller action append to the header the following lines
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:
Here\'s the NoCache
attribute proposed by mattytommo, simplified by using the information from Chris Moschini\'s answer:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : OutputCacheAttribute
{
public NoCacheAttribute()
{
this.Duration = 0;
}
}
回答6:
For MVC6 (DNX), there is no System.Web.OutputCacheAttribute
Note: when you set NoStore
Duration parameter is not considered. It is possible to set an initial duration for first registration and override this with custom attributes.
But we have Microsoft.AspNet.Mvc.Filters.ResponseCacheFilter
public void ConfigureServices(IServiceCollection services)
...
services.AddMvc(config=>
{
config.Filters.Add(
new ResponseCacheFilter(
new CacheProfile() {
NoStore=true
}));
}
...
)
It is possible to override initial filter with a custom attribute
[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);
}
}
Here is a use case
[NoCache]
[HttpGet]
public JsonResult Get()
{
return Json(new DateTime());
}
回答7:
Output Caching in MVC
[OutputCache(NoStore = true, Duration = 0, Location=\"None\", VaryByParam = \"*\")]
OR
[OutputCache(NoStore = true, Duration = 0, VaryByParam = \"None\")]
回答8:
Correct attribute value for Asp.Net MVC Core to prevent browser caching (including Internet Explorer 11) is:
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
as described in Microsoft documentation:
Response caching in ASP.NET Core - NoStore and Location.None