If you've not yet learned about user controls, you're missing a powerful feature in ASP.NET. User controls are page fragments that can be inserted into Web pages just like a Web control. The difference is that user controls retain their visual design in Visual Studio. This means that you can create reusable controls without having to try to write the HTML output yourself (as you would with a Web control).
What's more, the user control supports built-in caching, which can help improve performance by storing a pre-rendered copy of the control's output. This means that the control can be displayed without even running the code. This can greatly improve performance, especially when the same information is hit repeatedly.
How to cache user control
The process of caching a user control in .NET is very simple. You put an OutputCache directive at the top of the user control's ASCX file. This directive takes a duration attribute that indicates the length in minutes that the control will be cached. This alone is a great feature of ASP.NET; however, the functionality goes much farther by allowing for multiple copies of the control to be cached based on the parameters that the user control receives.
The duration attribute is joined by a VaryByParam, VaryByControl, or VaryByCustom. VaryByParam creates different cached copies of the control based on the query string and form post variables provided to the form. The VaryByControl attribute allows you to enter a string that will be used to differentiate copies of the control in the cache. The VaryByCustom attribute causes ASP.NET to call HttpApplication.GetVaryByCustomString to return the string that will be used to separate one cached copy of the control from another.
An OutputCache directive without any variance in parameters will look like this:
<%@ OutputCache Duration="60" VaryByParam="none" %>
An easy way to test the directive is to create a user control that displays the current time, copy it into two different user controls, and put the OutputCache on one of the two controls. Once you've done this, you can assemble a page that contains both controls. If one of the controls doesn't update the time when it's loaded the second time, you know that it's been cached.
Of course, varying by parameter is fine when you are getting the parameters from a query string; however, if the parameters to change the output of the control are not coming from a query string, this will not work.
Additional white paper resources
Vary by custom
The designers of ASP.NET decided, wisely, that they may not be able to anticipate every method of determining which cached version of a control developers might want. Because of this, VaryByCustom was added. It allows you to vary, for instance, the cached copy to display information from a user's profile. It might be the list of benefits that a member of a particular class should receive. A control that displays those benefits would need to know what class the user is, but this information is probably not going to be in the query string or a part of a form post. In order to control the different cached copy of the control, you'll have to resort to the VaryByCustom attribute and set up a GetVaryByCustomString() member of the global class.
The member function uses two parameters, the first being the HttpContext of the request that generated the call. This is necessary if there are variables in the session that must be considered, such as a user profile object. The second parameter is the argument string provided as the value for the VaryByCustom attribute in the control. This string is the complete value, not broken up or processed in any way. The expected return value is a string that will uniquely identify this particular instance of the cached copy of the control.
Your code should evaluate the incoming argument and provide the appropriate return string. For instance, the code in Listing A searches the user's session for the variables listed in the VaryByCustom attribute and returns the values of those session values as a part of a custom string:
Clearing the cache
Most of the time, the caching that you set up may be appropriate, but there may be times, particularly when you're trying to debug problems, when waiting for the cache to expire may be painful (that is, at least if you're as impatient as I am). For that reason, it's possible to clear the output cache for a user control (as well as a page). The Response.RemoveOutputCacheItem() is the method that will remove the item from the cache. However, there's a catch. RemoveOutputCacheItem only takes one parameter—the path of the item(s) to remove. Although the static method indicates by its name that it's clearing one item, in reality it clears all of the cached copies of the user control (or page) for a given path.
While this is typically not a problem in clearing items for debugging, it can be potentially challenging if you were expecting to use the function to clear a single version of the control. That control may have a few hundred different cached copies, and each of them would have to be regenerated.