What’s great about user controls is that—like other types of server controls—they can contain properties, fields, methods, and allow pages to interact with them. They also facilitate fragment caching when only portions of a page get cached while the rest of the content remains dynamic.
There is plenty of information about the various directives of user control caching. For example, see How To Perform Fragment Caching in ASP.NET by Using Visual C# .NET (KB 308378). I’d only like to point out one interesting gotcha.
I created a very simple (and useless) user control:
ascx
<%@ OutputCache Duration=”1200” VaryByParam=”None” %>
<asp:TextBox id=”FirstName” runat=”server” />
code-behind
public class MyUserControl : UserControl
{
protected TextBox FirstName;
public string UserFirstName
{
get { return FirstName.Text; }
set { FirstName.Text = value; }
}
}
and placed it on an equaly simple (and useless) page:
aspx
<%@ Register TagPrefix=”uc1” TagName=”MyUserControl”
Src=”MyUserControl.ascx” %>
…
<form id=”Form1” method=”post” runat=”server”>
<uc1:MyUserControl id=”MyUserControl1” runat=”server” />
</form>
…
code-behind
public class WebForm1 : Page
{
protected MyUserControl MyUserControl1;
protected override void OnLoad(EventArgs e)
{
string name = MyUserControl1.UserFirstName;
}
}
The control collects a hypothetic first name and exposes it via a property. The OutputCache directive instructs the page parser to create an instance of MyUserControl from cache which stays fresh for 20 minutes. I also enabled page tracing to see rendering of the control tree. In the trace I clearly see an instance of MyUserControl created the “normal’ way along with its only control: a text box.
…
_ctl0 System.Web.UI.StaticPartialCachingControl
MyUserControl1 ASP.MyUserControl_ascx
MyUserControl1:FirstName System.Web.UI.WebControls.TextBox
…
Note that the page parser placed the user control within a container of type StaticPartialCachingControl. This special control is able to add other controls from the ASP.NET cache, which is exactly what you see here. Since the page was requested for the first time, StaticPartialCachingControl dynamically created an instance of our user control, added it to the tree, rendered and cached it.
If you refresh this page now, you see the following control tree in the trace:
…
_ctl0 System.Web.UI.StaticPartialCachingControl
…
That’s it! Since the user control is already cached, no instance has been created! If I were to reference the UserFirstName property at this point, I’d get an exception because the control is null.
If you add a user control to a page dynamically, a PartialCachingControl is created instead, but the rest of the discussion applies to it in equal measure.
The point here is to be careful with a cached user control. Once it’s parsed, compiled and stashed away in cache, you can’t reference its methods or properties.