Downloads
144827_code.zip

The web developer community has long supported mobile website development. Developers have used a variety of techniques, some client-based and some server-based, to accommodate the widest range of browser clients. In this article, I'll discuss a feature in ASP.NET MVC 4 called display modes that gives ASP.NET web developers more help in supporting a variety of browsers in their mobile web applications. I will explain how using display modes helps with mobile browser detection in web apps, then demonstrate how to use display modes in a sample ASP.NET MVC 4 web application. But first, we'll look briefly at some options that have been available to web developers for dealing with mobile websites.

Handling Mobile Websites

One technique, specific to the client, has been to create a responsive web design, using Cascading Style Sheets (CSS) to expand or contract the website depending on the available viewport. Sites like this have rolled their own CSS or used a framework such as Twitter Bootstrap or the 960 Grid System. Another technique is to create a flexible design with percentage-based widths, so that the page naturally expands or contracts as the viewport changes. More options exist, and all these options are valid client-side options for handling multiple-sized viewports.

We are not limited to solutions on the client to solve the problem, however. When it comes to server-side technologies, mobile development has always been an option in Web Forms and ASP.NET MVC. For instance, Scott Hanselman previously published a custom view engine for ASP.NET MVC 3 that provides mobile support. The view engine detects information about the browser making the request, and if it determines that the browser is a mobile browser, the view engine serves up a mobile view to the client.

The WURFL and 51Degrees.mobi frameworks also support Web Forms and MVC; each of these products can detect a mobile device and redirect to another page or perform another action. Common to the .NET Framework is the ability to detect a mobile browser using the HttpRequest.Browser.IsMobileDevice property. However, solutions like WURFL and 51Degrees.mobi use a custom database with device configurations that provide more advanced capabilities than the .NET Framework.

With ASP.NET MVC 4, the .NET Framework solves some of these problems through the display modes feature but goes further in its solution. The display modes feature provides an alternative view mechanism that is displayed to the user when a certain condition is met. Display modes are not restricted to mobile views, though that is the feature's primary use. A display mode uses a lambda expression, matching a condition on the HttpContextBase class. If the condition matches, the specific view to the display mode is served up from the view engine to the user. Note that we are not talking about separate controllers, just the views themselves.

Creating a Display Mode

As I mentioned, the most common scenario is a mobile view, whereby the display mode detects a mobile browser and serves up a mobile view. However, limiting use of a display mode to only serving up mobile views does a disservice to the feature. Display modes can serve a variety of purposes. A display mode could be a mode that checks the current user's authentication status and serves up an unauthenticated view to the anonymous user. A display mode could check a single type of device (such as an iPad).

From a more technical perspective, a display mode in ASP.NET MVC is represented by the IDisplayMode interface and subsequently the DefaultDisplayMode class. The MVC framework uses the DefaultDisplayMode class to represent both desktop and mobile browsers.

It might seem odd to use the same class to represent both types of browsers. However, the display mode uses a public ContextCondition property with a getter and setter, taking a lambda expression that specifies a matching condition. This lambda expression accepts a reference to HttpContextBase, returning a Boolean; this means that whatever condition you want to match on the current request is pretty easily achievable. By default, the mobile definition checks the HttpContextBase.GetOverriddenBrowser().IsMobileDevice property to see whether the device is a mobile device. GetOverriddenBrowser() is a new extension method on HttpContextBase for getting an instance of the browser.

There are two ways to create a custom display mode. The first way is to instantiate the DefaultDisplayMode class and set the ContextCondition property, as explained previously. The second way is to create a class that inherits from the DefaultDisplayMode class and set the ContextCondition property in the constructor. I chose the latter option, as shown in Listing 1.

Listing 1: Opera Mobile Emulator Display Mode

public class OperaMobiDisplayMode : DefaultDisplayMode
{
        public OperaMobiDisplayMode()
                : base("Mobile")
        {
                ContextCondition = (context => IsMobile(context.GetOverriddenUserAgent()));
        }

        public static bool IsMobile(string useragentString)
        {
                return useragentString.IndexOf("Opera Mobi",
                                                StringComparison.InvariantCultureIgnoreCase) >= 0;
        }
}


One shortcoming of the .NET Framework's support for checking a mobile device is that .NET does not support Opera Mobile Emulator. To support Opera Mobile Emulator for testing purposes, the display mode in Listing 1 loads a mobile view when ASP.NET MVC detects a user agent string containing "Opera Mobi". Display modes always have a fallback; this means that if a view does not match the naming convention set up by the display mode, the default display mode is used. Using this design, we can easily support and isolate displays for all kinds of devices, simply by checking the user agent or any other HTTP request parameter.

Now that we have the display mode, we can register it in the Application_Start event handler, as in Listing 2. The display mode is inserted into the DisplayModeProvider.Instance.Modes collection. Once the display mode is in the collection, any request by an Opera Mobile Emulator serves up a mobile version, as defined by the string sent to the base constructor.

Listing 2: Registering Display Modes

protected void Application_Start()
{
        DisplayModeProvider.Instance.Modes.Insert(0, new UnauthenticatedDisplayMode());
        DisplayModeProvider.Instance.Modes.Insert(0, new OperaMobiDisplayMode())
}


Display modes are executed in order, so it's important that you insert them in the correct order. Note there are two already defined in the Modes collection.

Let's look at another example, this time thinking out of the box. For instance, maybe you want to display a view for a user who is not authenticated on the website. A display mode can interrogate the current principal for its authentication status and display a separate view just for unauthenticated users. Take a look at the code sample in Listing 3; since the display mode is based upon HttpContextBase (the type of the sole parameter), we can interrogate the current principal for its authentication status.

Listing 3: Display Mode for Displaying a Separate View for Unauthenticated Users

public class UnauthenticatedDisplayMode : DefaultDisplayMode {
public UnauthenticatedDisplayMode()
                : base("Unauthenticated")
        {
                this.ContextCondition = ctx => ctx.User == null || ctx.User.Identity.IsAuthenticated == false;
        }
}


In the base constructor, note that we pass "Unauthenticated", which needs to be part of the name of the view (as in Home.Unauthenticated.cshtml).