Reputation: 15243
Here's a very small sample Razor Page:
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<h1>
@DateTime.Now.ToString()
</h1>
//model
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
If I use this code, the time will update every 30 seconds which is what is intended:
<cache expires-after="TimeSpan.FromSeconds(30)">
<h1>
@DateTime.Now.ToString()
</h1>
</cache>
However, adding the ResponseCache
attribute to the model doesn't do this:
[ResponseCache(Duration = 30)]
public class IndexModel : PageModel
After doing some research it seems like the attribute only sends the appropriate headers to the client, asking it to cache the content. How can I store the entire response in memory so when the user asks for the specific page, the server just sends the cached response and eliminate the process of computing the result again?
Also, with the <cache>
tag helper, I couldn't find a way to invalidate the cached entry. So one scenario for me would be to cache every single page in memory for 30 days and if I change something on the admin panel, I would then invalidate the cache for that specific item so the next request would produce the fresh result. I used to do this on Asp.Net MVC 3+ but couldn't find any method to achieve the same result in Asp.Net Core 3.1
Upvotes: 10
Views: 1773
Reputation: 4621
From your question it seems you might need to roll out your own version
How can I store the entire response in memory so when the user asks for the specific page, the server just sends the cached response and eliminate the process of computing the result again?
See the source of https://github.com/dotnet/aspnetcore/blob/master/src/Mvc/Mvc.Core/src/ResponseCacheAttribute.cs
And
It seems that it sets headers only.
You may implement your own version of caching like this one
https://www.devtrends.co.uk/blog/custom-response-caching-in-asp.net-core-with-cache-invalidation
See CachedPage class in above example.
Upvotes: 1
Reputation: 737
Edit: No, it doesn't work (I cannot delete this answer).
Browsers often add a cache control header on reload that prevent the middleware from serving a cached page.
Therefore, it doesn't work and I don't see how this could be any useful besides machine-machine requests using specially crafted requests.
Use a developer tool that permits setting the request headers explicitly, such as Fiddler or Postman.
I haven't tested it yet, but it looks like the "Response Caching Middleware" could be the answer.
https://learn.microsoft.com/en-us/aspnet/core/performance/caching/response?view=aspnetcore-3.1
For server-side caching that follows the HTTP 1.1 Caching specification, use Response Caching Middleware. The middleware can use the ResponseCacheAttribute properties to influence server-side caching behavior.
Response Caching Middleware in ASP.NET Core:
https://learn.microsoft.com/en-us/aspnet/core/performance/caching/middleware?view=aspnetcore-3.1
The middleware determines when responses are cacheable, stores responses, and serves responses from cache.
You'll not always get a cached response, though.
The middleware respects the rules of the HTTP 1.1 Caching specification. The rules require a cache to honor a valid Cache-Control header sent by the client. Under the specification, a client can make requests with a no-cache header value and force the server to generate a new response for every request. Currently, there's no developer control over this caching behavior when using the middleware because the middleware adheres to the official caching specification.
In addition
Caching should only be enabled for content that doesn't change based on a user's identity or whether a user is signed in.
Upvotes: 0