How to avoid the exception “Substitution controls cannot be used in cached User Controls or cached Master Pages.”

Recently I wrote example about using user controls with donut caching. Because cache substitutions are not allowed inside partially cached controls you may get the errorSubstitution controls cannot be used in cached User Controls or cached Master Pages when breaking this rule. In this posting I will introduce some strategies that help to avoid this error.

How Substitution control checks its location?

Substitution control uses the following check in its OnPreRender method.

protected internal override void OnPreRender(EventArgs e){    base.OnPreRender(e);    for (Control control = this.Parent; control != null;            control = control.Parent)    {        if (control is BasePartialCachingControl)        {            throw new HttpException(SR.GetString("Substitution_CannotBeInCachedControl"));        }    }}

It traverses all the control tree up to top from its parent to find at least one control that is partially cached. If such control is found then exception is thrown.

Reusing the functionality

If you want to do something by yourself if your control may cause exception mentioned before you can use the same code. I modified the previously shown code to be method that can be easily moved to user controls base class if you have some. If you don’t you can use it in controls where you need this check.

protected bool IsInsidePartialCachingControl(){    for (Control control = Parent; control != null;        control = control.Parent)        if (control is BasePartialCachingControl)            return true;     return false;}

Now it is up to you how to handle the situation where your control with substitutions is child of some partially cache control. You can add here also some debug level output so you can see exactly what controls in control hierarchy are cached and cause problems.