CodeProject, Software Development

Injecting a Dependency into an IHttpModule with Unity

We’re starting a new project, and as part of that we want to get better at certain things. One is unit testing the things we didn’t last time around that were in hard-to-reach places. Pretty much most things that interact with ASP.NET have hard-to-reach places. Even ASP.NET MVC, which was supposed to be wonderful and much more unit testable that vanilla ASP.NET, has lots of places where this falls down completely. However, we’re gradually finding way to overcome these obstacles.

In this post, I’m going to concentrate on custom IHttpModule implementations.

We have a custom IHttpModule that requires the services of another class. It is already set up in our IoC container and we just want to inject it into the module we’re writing. However, modules are instantiated by ASP.NET before our IoC framework can get to it.

How I got around this was by creating an additional module (an InjectorModule) that wired up all the other modules that needed dependencies injected using Unity’s BuildUp method to inject the dependency into the existing object.

Setting up the HttpApplication

The application object stores the container and implements an interface that the InjectorModule can access the container through.

public interface IHttpUnityApplication
    IUnityContainer UnityContainer { get; } 

And the Application class in the global.asax.cs file looks like this:

public class MvcApplication : System.Web.HttpApplication, IHttpUnityApplication
    // This is static because it is normal for ASP.NET to create
    // several HttpApplication objects (pooling) but only the first
    // will run Application_Start(), which is where this is set.
    private static IUnityContainer _unityContainer;

    protected void Application_Start()
        _unityContainer = UnityBootstrapper.Initialise();
	// Do other initialisation stuff here

    // This implements the IHttpUnityApplication interface
    public IUnityContainer UnityContainer
        get { return _unityContainer; }

The UnityBootstrapper initialises the container for MVC, it is created by the Unity.Mvc4 NuGet package (there’s also a Unity.Mvc3 package too). You can read more about it here.

The InjectorModule

Next up the InjectorModule is created

public class InjectorModule : IHttpModule
    public void Init(HttpApplication context)
        // Get the IoC container from the application class through
        // the common interace.
        var app = (IHttpUnityApplication) context;
        IUnityContainer container = app.UnityContainer;

        // Wire up each module that is registered with the IoC container
        foreach (var module in context.GetRegisteredModules(container))
            container.BuildUp(module.GetType(), module);

    public void Dispose()

I’ve also been a wee bit sneaky and created an extension method on HttpApplication to work out which are the registered modules so that the code above is a bit nicer. That code is:

public static class HttpApplicationExtensions
    public static IEnumerable GetRegisteredModules(this HttpApplication context, IUnityContainer container)
        var allModules = context.Modules.AllKeys.Select(k => context.Modules[k]);
        var registeredModules = allModules.Where(m => container.IsRegistered(m.GetType()));
        return registeredModules;

Wiring it all up

The container must be told which modules have dependencies to inject and what properties to set. e.g.

    new InjectionProperty("TheDependentProperty"));

MyCustomModule is the class that implements the IHttpModule interface, and you need to supply an InjectionProperty for each of the properties through which the IoC containers will inject a dependency.

You can also decorate the properies with the [Dependency] attribute, but then you are just wiring in a dependency on the IoC container itself… which is not good.

Finally, this new module has to be wired up in the web.config file

      <add name="InjectorModule"
           type="Web.IoC.Unity.InjectorModule" />
      <!-- Other modules go here, after the Injector Module -->

By putting the Injector module ahead of other modules in the web.config it means it gets a chance to run and inject the depedencies into other modules that have yet to be initialised.

Other considerations

The IHttpModule interface defines a method, Init(), that takes an HttpApplication as a parameter. Naturally, that’s difficult to mock out in a unit test.

What I did was to extract all the bits that I needed in the Init() method and pass them to another method to do the work. For example, HttpContext is easy to do because ASP.NET MVC provides an HttpContextWrapper and the method that is doing all the work just takes an HttpContextBase, which is easily mocked in a unit test.

public void Init(HttpApplication context)
   var wrapper = new HttpContextWrapper(context.Context);
public void InitImpl(HttpContextBase httpContext)
    // Do stuff with the HttpContext via the abstract base class
Software Development

Authenticating Across Virtual Directories

If you have an application set up in a way similar to the previous post, which is essentially a domain that contains a number of web application hosted in various virtual directories on the server.

In my previous example, the root of the domain contains the application that contains the account management (the sign in, password retrieval, account set up, etc.), however each of the applications in each virtual directory must know who is logged in.

Assuming you are using the .NET’s built in authentication mechanisms this is unlikely to work out of the box. There is some configuration that need to happen to allow each of the applications to sync up.

Setting up the web.config file

In MVC 4 Forms Authentication must be set up explicitly.

  <authentication mode="Forms">
  <!-- Other config settings -->

To ensure that each application can decrypt the authentication ticket in the cookie, they all must share the same machine key as by default IIS will assign each application its own encryption and decryption keys for security.

  <machineKey decryptionKey="10FE3824EFDA35A7EE5E759651D2790747CEB6692467A57D" validationKey="E262707B8742B1772595A963EDF00BB0E32A7FACA7835EBE983A275A5307DEDBBB759B8B3D45CA44DA948A51E68B99195F9405780F8D80EE9C6AB46B9FEAB876" />
  <!-- Other config settings -->

Do not use the above key – it is only an example.

These two settings must be shared across each of the applications sitting in the one domain.

Generating a Machine Key

To generate a machine key:

  • Open “Internet Information Services (IIS) Manager” on your development machine.
  • Set up a dummy application so that it won’t affect anything else on the machine.
  • Open up the Machine Key feature in the ASP.NET section

    IIS Manager
    IIS Manager
  • (1) In the “Validation key” section uncheck “Automatically generate at runtime” and “Generate a unique key for each application”.

    Machine Key Configuration in the IIS Manager
    Machine Key Configuration in the IIS Manager
  • (2) In the “Decryption key” section uncheck “Automatically generate at runtime” and “Generate a unique key for each application”.
  • (3) Click “Generate Keys” (this will change the keys randomly each time it is pressed)
  • (4) Click “Apply”

The web.config for this web application will now contain the newly generated machine key in the system.web section. Copy the complete machineKey element to the applications that are linked together.

There is an “Explore” link on the site’s main page in IIS to open up Windows Exporer on the folder which contains the web site and the web.config file.

Open Source Software, Software Development, Xander.PasswordValidator

Xander.PasswordValidator – The config file

Earlier in this series I introduced the config file, but I didn’t say much about it other that show an example. In this post I’ll go in to more detail.

Defining the config section

To define the section:

<!-- Set up other config sections here—>
   <sectionGroup name="passwordValidation">
      <section name="rules" type="Xander.PasswordValidator.Config.PasswordValidationSection, Xander.PasswordValidator, Version=, Culture=neutral, PublicKeyToken=fe72000dffcf195f" allowLocation="true" allowDefinition="Everywhere"/>
   </sectionGroup> </configSections>

This defines the configuration section will will appear later in the config file.

An example of the config section itself:

<!-- The configuration section that describes the configuration for the password validation -->
   <rules minimumPasswordLength="6" needsNumber="false" needsLetter="false" needsSymbol="false">
     <wordListProcessOptions checkForNumberSuffix="true" checkForDoubledUpWord="true" checkForReversedWord="true" />
       <add value="FemaleNames"/>
       <add value="MaleNames"/>
       <add value="MostCommon500Passwords"/>
       <add value="Surnames"/>
       <add file="WordLists/MyCustomWordList.txt" />
       <add file="WordLists/MyOtherCustomWordList.txt" />
   </rules> </passwordValidation>

The rules

The rules section defines the actual rules by which the passwords will be validated.

<rules minimumPasswordLength="13" needsNumber="true" needsLetter="true" needsSymbol="true">
  • minimumPasswordLength: a positive integer that defines the minimum number of characters needed for a valid password. It is optional and if missing will default to 8.
  • needsNumber: Boolean that indicates whether the password needs a number in it. It is optional and if missing will default to true.
  • needsLetter: Boolean that indicates whether the password needs a letter in it. It is optional and if missing will default to true.
  • needsSymbol: Boolean that indicates whether the password needs a symbol in it. It is optional and if missing will default to false.

Rules can have a number of child elements also.

  • wordListProcessOptions: A set of options for how the word lists are processed
  • standardWordLists: A collection of built in word lists to use to check the password against.
  • customWordLists: A collection of custom word lists to use to check the password against.

The word list process options

By default, checking the password against the word lists only checks to see if the password is in a word list. These are additional options for checking against the word lists.

<wordListProcessOptions checkForNumberSuffix="true" checkForDoubledUpWord="true" checkForReversedWord="true" />
  • checkForNumberSuffix: Indicates whether the password should be checked to see if it is simply in the word list with an additional digit appended. This is optional, and by default is false.
  • checkForDoubledUpWord: Indicates whether the password should be checked to see if it is the same sequence repeated over again, and if it is to see if the first half is in the word list. This is optional and the default value is false.
  • checkForReversedWord: Indicates the a reversed form of the password should be checked to see if it in the word list. This is optional and the default value is false.

Standard word lists

This element is a container for a collection of standard word list items.

       <add value="FemaleNames" />
       <add value="MaleNames" />
       <add value="MostCommon500Passwords" />
       <add value="Surnames" />

The valid words list are:

Custom word lists

This element is a container for a collection of file paths to plain text files that contain custom word lists to check against. A word list file is simply a plain text file with one word per line.

       <add file="WordLists/MyCustomWordList.txt" />
       <add file="WordLists/MyOtherCustomWordList.txt" />

The paths are relative to the working directory of the application in which the password validator is operating. In an ASP.NET web application the paths should be prefixed with the ~ to ensure they are correctly mapped on the server relative to the root of the web application.

Software Development

Umbraco installation woes

Recently, I created an Umbraco site on one machine and I wanted to move it to another. I say site, there was nothing in it. It was really a basic database, but I’d configured it with just an empty install before I zipped up the solution and all the files in it.

When I unzipped the files on to a new machine every time I tried to run the Umbraco install routine it would redirect me to a log on page even although the site had only a completely empty database to connect to (not a single table because the installation hadn’t run yet).

The reason is that on installation part of the web.config is updated.

<add key="umbracoConfigurationStatus" value="4.8.0" />

And that indicates to Umbraco that the installation is complete. So, allow installation to proceed normally remove the value and the installation can start normally, like this:

<add key="umbracoConfigurationStatus" value="" />
Software Development, Tip of the Day

Tip of the day: Expire a cookie, don’t remove it

I recently found a bug in my code that I couldn’t fathom initially until I walked through the HTTP headers in firebug. In short, you cannot simply remove a cookie by calling Remove(cookieName) on the HttpCookieCollection. That will have no effect. You have to expire the cookie in order for it to be removed.

In other words, you need code like this:

HttpCookie cookie = new HttpCookie("MyCookie");
cookie.Expires = DateTime.UtcNow.AddYears(-1);

When you create a cookie, the response from the server will contain an HTTP Header called Set-Cookie that contains the value of the cookie.

For example, if we create a cookie like this:

HttpCookie cookie = new HttpCookie("MyCookie");
cookie.Value = "The Value of the cookie";

Then the Response will contain this:

Set-Cookie    MyCookie=The Value of the cookie; path=/

Each subsequent request to the server will contain the cookie, like this:

Cookie        MyCookie=The Value of the cookie

The responses from the server do not contain the cookie unless the server is updating the value of the cookie.

When the cookie is to be removed forcefully, the server must update the cookie with a new expiry, like this:

HttpCookie cookie = new HttpCookie("MyCookie");
cookie.Expires = DateTime.UtcNow.AddYears(-1);

The response will then have this header:

Set-Cookie    MyCookie=; expires=Mon, 20-Sep-2010 21:32:53 GMT; path=/

And in subsequent requests the cookie won’t be present any more as the browser will have removed it.

Software Development

Installing a web site on a new server

Here are some blog posts that have been useful to me lately when I got caught out installing a website on a new server (I will eventually get that automated build and deploy process actually performing the deploy step successfully!!)

The configuration section ‘system.web.extensions’ cannot be read because it is missing a section declaration:

While installing a website on a new Windows Server I came across this error. In short, it was because the App Pool was set up as a .NET 2.0 application rather than a 4.0. The blog post explains what was going on and how to fix it.

[Resolved] Could not load file or assembly ‘XXXXX’ or one of its dependencies. An attempt was made to load a program with an incorrect format:

Although this didn’t help me in the end, it does suggest a solution. In my case, because of a third-party dependency that requires an x86 build, it couldn’t be used. In time that dependency will be removed, in the meantime the following was more helpful to me…

Could not load file or assembly ‘PresentationCore’ or one of its dependencies. An attempt was made to load a program with an incorrect format. : A solution:

This post did give me the pointer I needed to the setting that had to be changed to get the web site working.

Software Development

Friendly error messages with Microsoft Report Viewer Control

For a project I’m working on I’ve got to display data that’s coming from SSRS (SQL Server Reporting Services) on a web page for our users. One of the feedback items from the first round of user testing was that the error messages from the control were not helpful or friendly.

For example, if a user types in a date in an incorrect format the Report Viewer Control would return an error message to the user like this:

The value provided for the report parameter 'pToDate' is not valid for its type. (rsReportParameterTypeMismatch)

The user doesn’t know that “pToDate” is. The nearest possibly alternative on the page reads “To Date” so they could possibly take a good guess, but why risk support calls over something like that? And the “(rsReportParameterTypeMismatch)” is likely to mean even less to a user. Why should they even have to see things like that?

So I set about trying to change that.

In fact the control gives you no way to alter the error messages that it shows. There is a ReportError event that you can subscribe to and indicate you’ve handled the error, but no where to provide a better error message.

With that in mind I thought that what I’d do is create a Label on the page to hold the error message and populate it if an error occurred.  However, I found that while I could get the message to display initially, I could not get it to go away once the user had corrected the error.

What I had was this:


<asp:Label runat="server" ID="ReportErrorMessage" Visible="false"
<rsweb:reportviewer runat="server" ID="TheReport"  Font-Names="Verdana"
                    Width="100%" Height="100%" Font-Size="8pt"
                    InteractiveDeviceInfos="(Collection)" ProcessingMode="Remote"
                    WaitMessageFont-Names="Verdana" WaitMessageFont-Size="14pt"
    <serverreport reportpath="/Path/To/The/Report"
                  reportserverurl="" />


protected void TheReport_ReportError(object sender, ReportErrorEventArgs e)
  if (e.Exception.Message.Contains("rsReportParameterTypeMismatch"))
    ReportErrorMessage.Text = BuildBadParameterMessage(e);
    ReportErrorMessage.Text = BuildUnknownErrorMessage(e);

  ReportErrorMessage.Visible = true;
  e.Handled = true;

protected void TheReport_ReportRefresh(object sender, CancelEventArgs e)
  ReportErrorMessage.Visible = false;
  ReportErrorMessage.Text = string.Empty;

Somehow or another the initial message was being set, however the changes in TheReport_ReportRefresh were not being applied despite me verifying the code was being run.

I eventually realised that the report viewer control was not performing a full postback, but just a partial postback and that I needed to put the Label control inside an update panel. Like this:

<asp:UpdatePanel runat="server">
        <asp:Label runat="server" ID="ReportErrorMessage" Visible="false"

Once I did that the message appeared and disappears correctly.