asp.netcachinguser-controlsruntimeloadcontrol

How to LoadControl a control that uses VaryByControl OutputCache, specifying values for properties


I've got a user control that should use caching, with VaryByControl. The .ascx file looks like this :

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TestControl.ascx.cs" Inherits="mynamespace.TestControl" %>
<%@ OutputCache Duration="10" Shared="true" VaryByControl="Test" %>
<p id="SomeText" runat="server">Nothing</p>

The TestControl class in the code-behind file has a int Test {...} property and an Page_Load() event handler that fills the SomeText paragraph with:

SomeText.InnerText = string.Format(@"Test={0} at {1}", Test, DateTime.Now)

I've got a .aspx file that looks like this:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestPage.aspx.cs" Inherits="mynamespace.TestPage" %>
<%@ Register TagPrefix="xxx" TagName="TestControl" Src="Controls\TestControl.ascx" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <xxx:TestControl Test="6" runat="server" />
    <xxx:TestControl Test="7" runat="server" />
    <hr />
    <asp:PlaceHolder ID="Suport" runat="server" />
</body>
</html>

The two <xxx:TestControl> tags properly load instances of TestControl with Test set to the expected value, I can refresh the browser a few times and I can see the cache properly doing it's job.

Now I'd like to fill the <asp:PlaceHolder ID="Suport" /> with some instances of TestControl, using varying Test values, that should all benefit from proper caching. I'm trying to use the LoadControl method, but I can't find a way to specify a value for the Test property. I expect such a method to exist, after all asp.net code loading the .aspx page manages to find the proper cached control. All I get is an instance of PartialCachingControl without CachedControl initialized and at runtime the rendered TestControl shows Test has the default value of 0.

This is how my .aspx Page_Load() event handler looks like:

protected void Page_Load(object sender, EventArgs e)
{
    PartialCachingControl tc = (PartialCachingControl) LoadControl(@"Controls\TestControl.ascx");
    if (tc.CachedControl != null)
        ((TestControl)tc.CachedControl).Test = 67;            
    Suport.Controls.Add(tc);
}

Edit

I could work around the problem by caching the whole page, but it just seems odd that I can't find a way to do it this way. Especially since invoking the control through the ASPX file works as expected (proving there's a way).

Edit 2

Hmm, no answers so far. I started a bounty, hopefully it gets a bit more attention.


Solution

  • I think you have misunderstood the VarByControl-property, it does not tell the cache to change upon a property on the control, but on the ID of controls on the page. Here is the text from MSDN:

    The VaryByControl property is set to fully qualified control identifiers, where the identifier is a concatenation of control IDs starting from the top-level parent control and delimited with a dollar sign ($) character.

    In your case you can maybe set VaryByCustom instead of VaryByControl and generate a cache key from the Test-property-value and vary it if it changes.