Reputation: 1641
There is parent user control, as seen below.
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="TestUserControl.ascx.cs" Inherits="TestUserControl" %>
<%@ Register Src="~/UserControls/ChildUserControl.ascx" TagName="ChildUserControl" TagPrefix="FLI" %>
<div>
<FLI:ChildUserControl ID="child1" runat="server"/>
</div>
The child usecontrol has pulic property MatchDescription
, which is set in the Page_Load
of the parent control. I want to cache multiple versions of the child control, based on the MatchDescription
property.
Problem is, the MatchDescription
property cant be set in Page_Load
, as the cached copy of the child control is used once its available.
How can i fix this problem?
Thanks!
Upvotes: 1
Views: 462
Reputation: 14938
It looks like using GetVaryByCustomString
is the way to go here. My proof of concept consisted of the following:
MatchDescription
.GetVaryByCustomString
method.WebUserControl.ascx
Add the following to the markup on the control:
<%@ OutputCache Duration="120" VaryByParam="none" VaryByCustom="MatchDescription" %>
This specifies the duration (in seconds) to cache the control and VaryByCustom="MatchDescription"
specifies the name of the parameter we will be caching on.
WebUserControl.ascx.cs
public partial class WebUserControl1 : System.Web.UI.UserControl
{
public string MatchDescription { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
object description = this.Context.Application["MatchDescription"];
if (description != null)
{
this.MatchDescription = description.ToString();
}
else
{
this.MatchDescription = "Not set";
}
Label1.Text = "Match description: " + this.MatchDescription;
}
}
This will check for the existance of the MatchDescription
value. Because of the way the code in the parent page works, you should never see "Not set", though in your implementation it may be useful just in case the value is not set.
Global.asax
Add a Global.asax
file to your project and add in the following method:
public override string GetVaryByCustomString(HttpContext context, string custom)
{
if (custom == "MatchDescription")
{
object description = context.Application["MatchDescription"];
if (description != null)
{
return description.ToString();
}
}
return base.GetVaryByCustomString(context, custom);
}
This is the bit that checks for the MatchDescription
associated with the cached control. If it is not found the control will be created as normal. context.Application
is used because we need a way to communicate the description value between the parent page, the user control and the global.asax file.
WebForm.aspx.cs
public partial class WebForm : System.Web.UI.Page
{
private static string[] _descriptions = new string[]
{
"Description 1",
"Description 2",
"Description 3",
"Description 4"
};
protected override void OnPreInit(EventArgs e)
{
//Simulate service call.
string matchDescription = _descriptions[new Random().Next(0, 4)];
//Store description.
this.Context.Application["MatchDescription"] = matchDescription;
base.OnPreInit(e);
}
protected void Page_Load(object sender, EventArgs e)
{
var control = LoadControl("WebUserControl.ascx") as PartialCachingControl;
this.Form.Controls.Add(control);
//Indicate whether the control was cached.
if (control != null)
{
if (control.CachedControl == null)
{
Label1.Text = "Control was cached";
}
else
{
Label1.Text = "Control was not cached";
}
}
}
}
Note that in this code I am making/simulating the service call in the OnPreInit
method. This is necessary as it occurs in the page lifecycle before the GetVaryByCustomString
method.
Keep in mind that if a control has been cached, accessing it in the Page_Load
method, for example, will require code of this form:
if (control is PartialCachingControl &&
((PartialCachingControl)control).CachedControl =!= null)
{
WebUserControl1 userControl = (WebUserControl1)((PartialCachingControl)control).CachedControl;
}
References:
My answer was inspired by: Any way to clear/flush/remove OutputCache?
I found the Pre_Init
hint in this question:
Output Caching - GetVaryByCustomString based on value set in PageLoad()
This KB article discusses why the PartialCachingControl.CachedControl
property can always return null:
http://support.microsoft.com/kb/837000
Upvotes: 1