5

My application uses ASP.NET MVC 5 with OutputCache (in detail, we use MVCDonutCaching) to cache high traffic sites and expensive routes.

Some of the Actions have a Custom ActionFilter which adds a Content-Range header depending on the view model. Without caching it works like charm. When the cache is enabled the first hit is ok (Content-Range header is present in the response) - but the second one only contains Content-Type and the HTML/JSON Response and our custom Content-Range header is missing (which breaks the client functionality).

Is there any way to enable proper header caching without writing an own OutputCache implementation?

Thank you very much.

3
  • Is it even making request or using locally cached request, what is the OutputCache set for? Commented Sep 8, 2014 at 20:41
  • The request is sent to server and answered by it. The request goes through routing and stops on the DonutOutputCache ActionFilter which serves a copy of the original Http Content, set's the content type and some cache headers. Commented Sep 8, 2014 at 21:00
  • Is the custom header action filter annotation before or after the output cache annotation? Commented Sep 9, 2014 at 11:10

1 Answer 1

1

The cached response is a "304 - Not Modified" HTTP Response, and that kind of response is not expected to return entity headers (except some exceptions like "Last-Modified").

The "Content-Range" header you are trying to return is an entity header:

http://www.freesoft.org/CIE/RFC/2068/178.htm

Here is a full list of Entity headers:

https://www.rfc-editor.org/rfc/rfc2616#section-7.1

The reason why 304 is not returning entity headers is that the 304 response is not supposed to return a full representation of the target resource, since nothing changed.

The 304 (Not Modified) status code indicates that a conditional GET or HEAD request has been received and would have resulted in a 200 (OK) response if it were not for the fact that the condition has evaluated to false. In other words, there is no need for the server to transfer a representation of the target resource because the request indicates that the client, which made the request conditional, already has a valid representation;

That means that entity headers should not be transferred again. This ensures consistency, and also has some performance benefits.

If the conditional GET used a strong cache validator (see section 13.3.3), the response SHOULD NOT include other entity-headers. Otherwise (i.e., the conditional GET used a weak validator), the response MUST NOT include other entity-headers; this prevents inconsistencies between cached entity-bodies and updated headers.

https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-p4-conditional-23#section-4.1

My conclusion is that ASP.NET and IIS are interpreting this specification correctly, and what you are trying to do is NOT supported. A prove for that is that Apache, and other popular web servers do the same as explained above.

If you still need that header in your 304 you will have to identify and replace (if possible) the components responsible for filtering the 304 responses.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.