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.