Sunday, February 19, 2006

WebPart Skins & User Controls

Today, we're developing a web part. This web part has the requirement that administrators be able to edit the user interface through the web UI. Since more than instance may be deployed to a single web site and one web site can span more than one host, we cannot simply provide an editor for a file.

What we really need is the ability to treat one of our web part's properties as a user control. Of course, user controls are useless if they can't have scripts or databinding in them, so we cannot simply use TemplateControl.ParseControl; we have to use LoadControl. Now we see our problem: LoadControl requires a file but we want to persist our control as a property.

The solution ends up being pretty simple: We store the body of our skin as a property of our web part with freshness data. In the solution provided here, our freshness data is a Guid and the body of our skin is the text portion of a user control (we are foregoing code-behind, for now). Every time an instance of our web part is rendered, it tries to load its skin from a cache directory (which is also specified via property) using the Guid as its name. If the file does not exist, we create it.

The result is, effectively, every time an administrator saves a change to a web part, a new use control will be created on every host. Since the user control is loaded from a file, it will get the advantage of ASP.NET's caching & compilation infrastructure; meaning it can have custom code and data-bindings in it.

Unfortunately, Google Blogs screws up source code. You can download an example here.

A nightly job can clean up old items by simply deleting all the files in the cache folder: the ones worth saving will get regenerated the next time they are needed anyway.

"Why?" you ask, or maybe, "Why not just use files?" I cannot answer that. I mean: I know the answer; I just can't give it to you right now. There are some out there who know why already. To anyone who asks "why" the only legal answer I can give you is "you'll see."