Rambling about ASP.NET Themes

If I go to the trouble of designing multiple ASP.NET Themes using skin and css files, chances are I will let a user choose the theme they find most pleasing. To let the user choose a theme, I’d first have to know what themes are available….

Plan 1

I could maintain the list of available themes in a configuration file, or in a database table. When I add new themes, I’ll have to update the file or table. A better design would be for the application to figure out which themes are available auto-magically, perhaps by using a class provided by ASP.NET….

Plan 2

Digging around, I find the IThemeResolutionService interface and it’s GetAllThemeProviders method. Each ThemeProvider encapsulates a theme. Unfortunately, the service appears to be available only at design time.

Due to the dynamic compilation features in ASP.NET, I figure there is no foolproof way to see all available themes. Even if I reflected every Type in the AppDomain, some themes may still be left on disk and un-compiled. Themes … on disk …

Plan 3

A simple solution would just look at what directories are available underneath the App_Themes directory. Without any error checking, the code would look like:

string themesPath = Server.MapPath("~/App_Themes");

List<string> themes = new List<string>();
foreach (string d in Directory.GetDirectories(themesPath))
{
  
// strip away all but the directory name            
  themes.Add(
      d.Substring(
        d.LastIndexOf(
Path.DirectorySeparatorChar) + 1
      )
    );
}

The above code seems fine until I start thinking about how it could break. It occurs to me that the ASP.NET plumbing doesn’t look directly at the file-system, but sees files and directories through virtualization goggles. There is probably a safer way to write the code, just in case the themes live in a database, or get pre-compiled away….

Plan 4

VirtualPathProvider vPathProvider;    
vPathProvider =
HostingEnvironment.VirtualPathProvider;

VirtualDirectory themeDirectory;
themeDirectory = vPathProvider.GetDirectory(
"~/App_Themes");

List<string> themes = new List<string>();
foreach (VirtualDirectory d in themeDirectory.Directories)
{
  themes.Add(d.Name);
}

Now, I’m cooking with oil and a bottle of sherry.
Except … the rumors of the demise of global themes have been greatly exaggerated…

Plan 5

At some point in the preview builds of ASP.NET, Microsoft shipped a couple global themes. Although the themes themselves were dropped around beta 2, the ability to define global themes for all applications still exists. See the bottom of “How to: Define ASP.NET Page Themes” to setup global themes under WebDev and IIS.

Although I found it possible to get to the global themes directory using the VirtualPathProvider and HttpRuntime.AspClientScriptVirtualPath, the solution was beginning to feel a bit clunky. Also, since global themes live outside an application’s home directory, there is no way to read the available theme directories when running at medium trust. (The themes are still available to skin a page, however).

Finally, I’ve arrived at…

Plan 6

Go back to plan 1 … or plan 4.

posted on Tuesday, December 20, 2005 11:42 PM by scott

Comments

Thursday, December 22, 2005 7:53 PM by Christopher Steen

# Link Listing - December 22, 2005

ASP.NET 2.0 Control Adapter Architecture [Via: Scott
Guthrie ]
Atlas ScriptManager Control [Via:...
Sunday, March 12, 2006 7:23 PM by K. Scott Allen

# Setting An ASP.NET Theme in the PreInit Event Handler

Let’s say I want the user to select their favorite theme for my application. I can make a list of available...
Monday, June 05, 2006 9:25 AM by Bryan Avery

# re: Rambling about ASP.NET Themes

Great little solution, well done for a good write-up
Tuesday, June 27, 2006 2:19 AM by Rick Strahl's WebLog

# Dynamic Themes assignment

I'm finishing up some code today for some dynamic skinning of an application and I ran into a funky behavior with themes where changing the theme in web.config seems to have no effect on the pre-compiled application. No big deal, since the app is now actually using an application driven themes assignment mechanism, but it seems odd that this wouldn't work. In this post I show my app driven implementation for switching and assigning themes dynamically.
Thursday, December 28, 2006 9:56 PM by The iWantiOffer Blog

# How to change themes dynamicly