• How to change the ASP.NET Page theme programmatically in CWAB

    Published by on October 3rd, 2009 1:25 am under CWAB, p&p, Patterns & Practices, Theming, WCSF

    No Comments


    One of things that we may need in a CWAB application is changing the ASP.Net page theme programmatically based on some logic.

    If we want to achieve this, probably we will quickly be aware which it presents some design challenges for us:

    • What is the best place to put your logic?
    • How should we expose the artifact which retrieves the theme name?
    • When and where must we set the theme in the ASP.Net page?

    That said, I think that a good idea could be creating a global service in the Shell Module to retrieve the theme. Because in this way we will consume this service from a page to set the theme programmatically.

    Inspired by this forum thread, the logic to determine that ThemeName is retrieved based on the name of site. in the sample explain below.

    If your not familiar with the topics listed below, consider taking a look to the links before starting with the steps I listed.:

    The steps to implement one of the possible solutions are the following:

    Creating the ThemeResolutionProvider service

    1. Create a new folder named Services under the Shell Module.
    2. Add a new interface named IThemeProvider in the Services folder and a new class named ThemeResolutionProvier in the Services folder.
    3. Update the IThemeProvider.cs with the following code:
      public interface IThemeProvider
          string GetThemeName();
    4. Implement ThemeResolutionProvider.cs like this:
      public class ThemeResolutionProvider : IThemeProvider 
          private IHttpContextLocatorService _httpContextLocatorService;
          public ThemeResolutionProvider([ServiceDependency] IHttpContextLocatorService httpContextLocatorService)
              this._httpContextLocatorService = httpContextLocatorService;
          public string GetThemeName()
              string themeName = string.Empty;
              var request = this._httpContextLocatorService.GetCurrentContext().Request;
              switch (request.Url.Authority)
                  case "YourSite":
                          themeName = "YourCustomeTheme";
                          themeName = "Default";
              return themeName;

      Note: if you examine this code you will notice that the constructor has an argument with an attribute ServiceDependecy. This is necessary to notify ObjectBuilder to inject the object (for further information visit Dependency Injection). Also notice that the IHttpContextLocatorService helps you to access the HttpContext (to obtain the name of the site from the module).

    Using the ThemeResolutionProvider service.

    1. Once you have created the service, you should register it as a Global Service in the ShellModuleInitializer class under the Shell project. So in this class, locate AddGlobalServices method and add the following code to the method body to register the theme service.
      protected virtual void AddGlobalServices(IServiceCollection globalServices) 
           //more code here 
           globalServices.AddNew<ThemeResolutionProvider, IThemeProvider>(); 
    2. Finally you just need to programmatically set the ThemeName in your page, by adding the following property to your page:
      public IThemeProvider ThemeResolutionProvider
                this.Theme = value.GetThemeName(); 

      Note:  Here the property has the ServiceDependency attribute, to notify ObjectBuilder that in the Page PreInit it has to inject an instance of the IThemeProvider. As the IThemeProvider is injected OnPreInit it is possible to set the theme. You can read more about that.

    Important: If you have just a few pages where you have to apply this behavior, this is a good approach. But take in account that you can create a base class which inherits from Microsoft.Practices.CompositeWeb.Web.UI.Page to implement this behavior for an entire website.

    I hope that this post helps you. As always your feedback is really appreciated.

    Tags: , , , ,


Follow me on Twitter