Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC OutputCache vary by * and vary by user cookie

I have an asp.net mvc 3 project and I have a home controller. I have tagged my Index action with this attribute:

[OutputCache(Location = System.Web.UI.OutputCacheLocation.Any, Duration = 120, VaryByParam = "*", VaryByCustom = "user")]
public ActionResult Index()
{
    return View();
}

The vary by custom with user is handled in Global.asax.cs to check the user cookie value so that caching changes based on whether the user is logged in or not and what user they are.

When I go to this page on my web server, I get these headers in the response:

Cache-Control   public, max-age=120
Content-Type    text/html; charset=utf-8
Content-Encoding    gzip
Expires Sun, 20 Mar 2011 21:50:09 GMT
Last-Modified   Sun, 20 Mar 2011 21:48:09 GMT
Vary    Accept-Encoding
Date    Sun, 20 Mar 2011 21:48:09 GMT
Content-Length  3105

Right off the bat, the Vary - Accept-Encoding value looks wrong, shouldn't it have sent a Vary - * instead?

I am rendering the User.Identity.Name property to this view as well and I am noticing that even when I log out it will still render the user name, until the 120 seconds expires.

public override string GetVaryByCustomString(HttpContext context, string custom)
{
    if (custom.Equals("user", StringComparison.OrdinalIgnoreCase))
    {
        HttpCookie cookie = context.Request.Cookies["user"];
        if (cookie != null)
        {
            return cookie.Value;
        }
    }
    return base.GetVaryByCustomString(context, custom);
}

Been playing with this for several hours, and am completely stuck, hopefully someone has an idea...

like image 651
jjxtra Avatar asked Mar 20 '11 21:03

jjxtra


People also ask

How Output cache works in MVC?

The output cache enables you to cache the content returned by a controller action. That way, the same content does not need to be generated each and every time the same controller action is invoked. Imagine, for example, that your ASP.NET MVC application displays a list of database records in a view named Index.

How does Output caching work in ASP net?

ASP.NET provides the following different types of caching: Output Caching : Output cache stores a copy of the finally rendered HTML pages or part of pages sent to the client. When the next client requests for this page, instead of regenerating the page, a cached copy of the page is sent, thus saving time.

How caching works in ASP.NET MVC?

In ASP.NET MVC, there is an OutputCache filter attribute that you can apply and this is the same concept as output caching in web forms. The output cache enables you to cache the content returned by a controller action. Output caching basically allows you to store the output of a particular controller in the memory.

Where is Output cache stored?

The output cache is located on the Web server where the request was processed. This value corresponds to the Server enumeration value. The output cache can be stored only at the origin server or at the requesting client. Proxy servers are not allowed to cache the response.


2 Answers

You can have IIS compress the response before it gets cached by setting dynamicCompressionBeforeCache="true" on the urlCompression element in your web.config. This will result in the expected Vary:* header being returned.

Excerpt, from the IIS Configuration Reference, about the dynamicCompressionBeforeCache attribute:

The dynamicCompressionBeforeCache attribute specifies whether IIS will dynamically compress content that has not been cached. When the dynamicCompressionBeforeCache attribute is true, IIS dynamically compresses the response the first time a request is made and queues the content for compression. Subsequent requests are served dynamically until the compressed response has been added to the cache directory. Once the compressed response is added to the cache directory, the cached response is sent to clients for subsequent requests. When dynamicCompressionBeforeCache is false, IIS returns the uncompressed response until the compressed response has been added to the cache directory.

like image 160
Jim Geurts Avatar answered Oct 03 '22 13:10

Jim Geurts


The problem was IIS dynamic compression. It fouls up the http headers. I solved it by rolling my own dynamic compression using an actionfilter.

like image 24
jjxtra Avatar answered Oct 03 '22 13:10

jjxtra