7

I would like to throw a 410 status code for a page that does some database lookups. However it seems that outputcache only caches 200 status code pages. Is there anyway around this? I want to cache 410 pages for a while so the database doesn't get it, but it just skips the cache and hits the database again.

[OutputCache(Duration = 3600, VaryByParam = "eventid,teamid,v,r")]
    public virtual ActionResult Team(int? teamId, int? eventId)
    {
Mike Flynn
  • 22,342
  • 54
  • 182
  • 341

1 Answers1

2

OutputCache and almost all HTTP level caches are designed to ignore failed responses, anything other more than 399, all status code above 399 are error codes.

You can manually set Response Headers like

context.Response.Headers.CacheControl = "public, max-age=3600"

This is what OutputCache does internally, however, OutputCache might also provide server level cache if setup.

But if you use CDN, I doubt they will respect cache control in case of failed response status codes.

But it is not recommended. Lets say for some reason user deletes the cookies or cookie gets corrupted. And user receives 410 error. And user goes back to login and logs in correctly, and now for same request user will continue to receive 410 for one hour.

Or otherwise let’s say your database is unavailable and database throws 410 error, so even with valid cookie or valid authorization, user will receive cached error response. Caching layer doesn’t know when not to cache.

Instead, you can use MemoryCache, to cache error results in your memory for couple of seconds without going to database each time. Though the results will still hit the web servers.

CloudFlare and Azure provides web application firewall, which allows intelligently blocking errornous traffic if you are worried about DDOS kind of attacks. This approach seems better than using HTTP Cache, as you will have no control over user's cache. And you can't programmatically clear cache after successful login.

Akash Kava
  • 39,066
  • 20
  • 121
  • 167
  • I am not sure if this is what I want. Are you saying if I put that code in on a 401 error that the outputcache will pick it up. I had to create a list in memory just for this issue. – Mike Flynn Aug 31 '22 at 23:05
  • No, OutputCache will ignore all errors above 399. You can manually set cache control. But again it is not advisable. You have two options, one use memory cache to reduce database server queries, or use Web application firewall to temporarily disable DDOS kind of attacks. Can you elaborate your scenario on why you want to cache 41* errors? – Akash Kava Sep 01 '22 at 06:02
  • Apple Calendar is hitting an endpoint two dozen times a day on past events. I want to throw a 404 error, but only when verifying from the database it was a past event. I dont want to hit the database everytime to verify this is a 404 page. I want to cache it for say a day throwing a 404 error. – Mike Flynn Sep 02 '22 at 12:37
  • In that case why do you want to throw error code, instead you can simply empty content with 200 status and configure your app to ignore empty successful results. This is how we are doing it. – Akash Kava Sep 03 '22 at 15:56
  • Because I would think Apple Calendar may stop making requests to past events if a 404 error is thrown. They certainly wont do it for a 200 status code. – Mike Flynn Sep 03 '22 at 16:21
  • You can use etag with cache control to reduce requests. For older or invalid requests, add immutable with cache control header with etag. – Akash Kava Sep 03 '22 at 16:23
  • I think with an upvote of 7, people want a better answer. Ill play around with it to see if it works ok. – Mike Flynn Sep 03 '22 at 20:09