Alireza Noori
Alireza Noori

Reputation: 15243

Caching full response on the server

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

Answers (2)

Ajay Kelkar
Ajay Kelkar

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

https://github.com/aspnet/Mvc/blob/d8c6c4ab34e1368c1b071a01fcdcb9e8cc12e110/src/Microsoft.AspNetCore.Mvc.Core/Internal/ResponseCacheFilter.cs

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

horacioj
horacioj

Reputation: 737

Edit: No, it doesn't work (I cannot delete this answer).

https://github.com/dotnet/AspNetCore.Docs/tree/master/aspnetcore/performance/caching/middleware/samples/3.x/ResponseCachingMiddleware

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

Related Questions