Drew's Blog

The Joys of Technology Explored

ASP.NET PartialCaching Problem: A Hacked Solution

Ok, I needed to prove to myself that my theory of being able to just use the built in PartialCachingControl would work if it's constructor were just public. So, I resorted to a little hackery and fell back on our friend System.Reflection to instantiate an instance of the class. Here's what I ended up with:

// 23.5-hour cache lifetime, shared across all pages
PartialCachingAttribute cacheAttribute = new PartialCachingAttribute(84600, null, null, null, true);

PartialCachingControl cacher = (PartialCachingControl)Activator.CreateInstance(typeof(PartialCachingControl), BindingFlags.NonPublic|BindingFlags.Public
|BindingFlags.ExactBinding|BindingFlags.Instance,
null, new object[] { typeof(StandardFooterCachedInnerControl), cacheAttribute, this.ID }, CultureInfo.InvariantCulture);

this.Controls.Add(cacher);

So, this logic is in the constructor of my “outer” control which is responsible for always being in the code tree and overrides Control::OnPreRender to emit the stylesheet link in the <head> of the page it is contained on. Then, as the code demonstrates, in that “outer” controls constructor I construct an instance of the PartialCachingControl using the PartialCachingAttribute data to specify the cache rules it should follow (in my case, I just need to cache the data for 23.5 hours and want it shared across all web pages) and specify the type of my inner control (i.e. StandardFooterCachedInnerControl) that actually does the rendering when the data is not cached.

As expected, this works flawlessly. This is a good enough solution for me since I always control the servers on which my control will be installed. However, it is not guaranteed to work for anyone writing third party server controls, since they might be installed with lesser code access preventing them from being able to use reflection. I can only hope that the ASP.NET team will respond to my bug report and properly expose these currently hidden little features in Whidbey for those of us who are writing more complex controls.

Posted: Nov 26 2003, 03:52 PM by drub0y | with 2 comment(s)
Filed under:

Comments

Rob Green said:

I'm having a vaguely related problem with PartialCaching at the moment for a solution that uses EPiServer CMS 5 as the base content management system.

Editors are meant to be able to place any number of predefined modules containing content in various layouts in the right hand column of every page, and I've written a module helper class which takes the data from the CMS, works out which user control should be loaded, and then loads it and assigns the data from the CMS to the user control by means of a single property.

All was well before I decided to introducing caching at a user control level, and obviously LoadControl then returns a PartialCachingControl which you have no ability to bind properties to.

Switching to the LoadControl method that takes a Type and parameter collection instead of string path to the user control looked like the next best solution, however I found using that method meant that any controls on the user control would then become null and cause exceptions to be thrown, even if it was the first run of the page.

Does your solution above achieve my goal?

# April 16, 2008 10:25 AM

Khurram Imtiaz said:

I am working in VS2010, with Framework 4.0

and I am having same problem. I use LoadControl() for dynamically loading usercontrols. Later i need to hold an instance of the underlying control. but the following statement raises an error. saying: Constructor not found.. etc.

(PartialCachingControl)Activator.CreateInstance(typeof(PartialCachingControl), BindingFlags.NonPublic|BindingFlags.Public

|BindingFlags.ExactBinding|BindingFlags.Instance, null, new object[] { typeof(StandardFooterCachedInnerControl), cacheAttribute, this.ID }, CultureInfo.InvariantCulture);

# September 5, 2011 9:01 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)