Dynamically Load Cached User Controls (and Live to Tell About It)

Learn to recognize — and avoid — this common caching snafu.

Jeff Prosise

October 30, 2009

2 Min Read
ITPro Today logo

Hot Tip

LANGUAGE: C#

ASP.NET VERSIONS:1.0 | 1.1

 

Dynamically Load Cached User Controls (and Live to TellAbout It)

Learn to recognize - and avoid - this common cachingsnafu.

 

By Jeff Prosise

 

Quick: can you spot the fatal flaw in the following ASPXfile and the accompanying user control (ASCX file)? It's a common problem thatASP.NET developers encounter all the time - one that causes the page to throwan exception every time it's loaded. And it's one for which the solution is farfrom obvious:

<%@ Import Namespace="System.Drawing" %>
<%@ Register TagPrefix="user"TagName="TimeControl"
  Src="Time.ascx" %>

 

</p> <p>void Page_Load (Object sender, EventArgs e)</p> <p>{</p><p>&nbsp;&nbsp;&nbsp;&nbsp;Control control =LoadControl ("Time.ascx");</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;Here.Controls.Add(control);</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; ((TimeControl)control).BackColor = Color.Yellow;</p> <p>}</p><p>

 

<%@ Control ClassName="TimeControl" %>
<%@ Import Namespace="System.Drawing" %>
<%@ OutputCache Duration="5"VaryByParam="None" %>

 

</p> <p>public Color BackColor</p><p>{</p><p>&nbsp;&nbsp;&nbsp;&nbsp;get { returnOutput.BackColor; }</p><p>&nbsp;&nbsp;&nbsp;&nbsp;set { Output.BackColor= value; }</p><p>}</p><p>&nbsp; </p><p>void Page_Load (Object sender, EventArgs e)</p> <p>{</p><p>&nbsp;&nbsp;&nbsp;&nbsp;Output.Text =DateTime.Now.ToLongTimeString ();</p><p>}</p><p>

 

The problem is that the Page_Load code that loads andinitializes the user control assumes the control's type is TimeControl. That'sa valid assumption if the control isn't cached, but the presence of an @OutputCache directive in the ASCX file means that LoadControl returns areference to a System.Web.UI.PartialCachingControl object rather than aTimeControl object, producing an InvalidCastException in the preceding code.

 

Here's the proper way to dynamically load and initialize auser control, independent of whether the control is cached. Note how the cachedcontrol's BackColor property is accessed: through the TimeControl referencestored in PartialCachingControl's CachedControl property. Also note thatPage_Load verifies that CachedControl isn't null before using it. That'sbecause CachedControl holds a valid TimeControl reference when LoadControlactually loads the control, but equals null when LoadControl retrieves thecontrol from the cache:

<%@ Import Namespace="System.Drawing" %>
<%@ Register TagPrefix="user"TagName="TimeControl"
  Src="Time.ascx" %>

 

</p> <p>void Page_Load (Object sender, EventArgs e)</p> <p>{</p><p>&nbsp;&nbsp;&nbsp;&nbsp;Control control =LoadControl ("Time.ascx");</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;Here.Controls.Add(control);</p> <p>&nbsp; </p><p>&nbsp;&nbsp;&nbsp;&nbsp;TimeControl time =null;</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;if (control is TimeControl)</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time =(TimeControl) control;</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;else if (control isPartialCachingControl &&</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((PartialCachingControl) control).CachedControl != null)</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time =(TimeControl)</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((PartialCachingControl) control).CachedControl;</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;if (time != null)</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.BackColor =Color.Yellow;</p> <p>}</p><p>

 

When loading user controls dynamically, structure yourcode this way and it will work with or without an @ OutputCache directive inthe ASCX file. Do it the other way, however, and you're in for a nasty surpriseif, after you've tested the page, someone adds a caching directive to the ASCXfile.

 

Jeff Prosise isauthor of several books, including Programming Microsoft .NET (MicrosoftPress). He also is a co-founder of Wintellect (http://www.wintellect.com), asoftware consulting and education firm that specializes in .NET. Contact Jeffat [email protected].

 

Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like