Disclaimer

Any opinions expressed here are my own and not necessarily those of my employer (I'm self-employed).

Nov 8, 2010

Lesson learned: HTTP modules can also affect WebResource.axd

HTTP modules can be very useful. In fact, I love them. The scope of this post is unfortunately not to explain what they are or what they do. If you're not familiar with what a HTTP module is, get an overview here and see how to create one here.

ASP.NET features some built in handlers: WebResource.axd and ScriptResource.axd. You'll see requests to these in any ASP.NET application, as they're used to serve builtin scripts for e.g. postback or client side form validation. By default, the ASP.NET application will configure these to expire from cache after a year.

Today I discovered a side effect I had not thought about. HTTP modules are loaded by the application, and are hooked into the event pipeline for each and every request handled by the ASP.NET application. In fact, this also includes requests to the WebResource.axd and ScriptResource.axd handlers!



Say you make an HTTP module that sets the cache policy for all responses — this is a nice trick to enforce a coherent cache policy for all pages across a website. Well, you just enforced your policy upon the built in handlers, which was probably not what you wanted. By default their response will be cached for an entire year, and reducing their time to live will obviously affect the load on your servers. You might even expire them immediately, forcing users to reload unchanged scripts on every page load (I know someone who did).

So, keep in mind that HTTP modules are also run for the built in handlers — or be prepared to taste the side effects.

As a final note, since we're discussing WebResource.aspx and caching: Make sure that the ASP.NET application is run with the <compilation debug="false"> setting, or else the framework will ensure that built in resources are not cached. ScottGu explains why on his blog, and one of the ASP.NET engineers elaborate further on the details of this setting on her blog.

To verifiy that the cache setting for the WebResource.axd is sane, use e.g. the Fiddler tool to inspect the response headers. You should see a date header with the current date, and an expires header with a date a year into the future, like this:

Date: Mon, 08 Nov 2010 14:57:24 GMT
Expires: Tue, 08 Nov 2011 14:57:24 GMT


Happy caching.

4 comments:

  1. It's a good trick to set cache expiration to "infinite" and instead use a version number in the query string to the resource. Then for each new version the users with the old outdated resource will immediately fetch the new resource from the server. If a resource lives for a long time without being changed then users never have to refetch it for that time.

    The page that references the resources either is always expired, or has a very short expiration.

    Ex: <script src="myfile.js?version=1"></script>

    ReplyDelete
  2. You're right! This is essentially what happens for resources served by WebResource.axd.

    ReplyDelete
  3. Awesome post, I learned something new today! I just forwarded your post to the BlogEngine.Net team as something they should be aware of.

    ReplyDelete
  4. I'm glad to hear that you found this information useful!

    ReplyDelete

Copyright notice

© André N. Klingsheim and www.dotnetnoob.com, 2009-2013. Unauthorized use and/or duplication of this material without express and written permission from this blog’s author and/or owner is strictly prohibited. Excerpts and links may be used, provided that full and clear credit is given to André N. Klingsheim and www.dotnetnoob.com with appropriate and specific direction to the original content.

Read other popular posts