Mobile devices, detection and views in .Net MVC

Mobile is hot, and will probably only get hotter. Sites need to be viewable on any kind of devices, so mobile detection is a hot issue.

Headers

But how do we detect mobile devices?

Every http request send to a page or website contains headers. These headers give us information about the sender. A nice tool to intercept a request and check the headers is fiddler. I have been using this tool for some years now, and I gained a lot of knowledge about requests and responses.


GET http://vicreative.nl/ HTTP/1.1
Host: vicreative.nl
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4

This is an example of a request to my website. This request is sent by Chrome.

The header we are looking for is the User-Agent. This header gives us information about the indentity of the browser who send the request. In above example, you can see that the request is send with a Chrome browser. This header will also tell us when the request is send by a mobile browser. I used a mobile device emulator to fake a mobile request:

GET http://www.vicreative.nl/ HTTP/1.1
User-Agent: Opera/9.80 (Android 2.3.7; Linux; Opera Mobi/46154) Presto/2.11.355 Version/12.10
Host: www.vicreative.nl
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, multipart/mixed, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Accept-Language: en-US,en;q=0.9
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Device-Stock-UA: Opera Mobile Emulator (no stock UA available)

Another header to keep in mind is the following:


X-Requested-With: XMLHttpRequest

This header information tells us that this is an ajax request. This is also used to determine the IsAjaxRequest property in a MVC controller.

So many devices

Now that we know that every device and browser sends its own User-agent header, you will probably think that it’s impossible to know all devices and browsers and operation systems. Well, you’re right.

I think that’s why the mobile device detection of Microsoft does not work so great. They just can’t update it enough to make it work for all devices.

So do not use HttpCapabilitiesBase.IsMobileDevice. It will only work if you override it and set the correct value.

There is a NuGet package which contains many devices and is updated regularly: 51 degrees.mobi

It also comes with a config, which allows you to set actions for mobile devices, like redirects.

Setting Mobile context

Whether a browser is mobile, can be manually overridden:

HttpContext.SetOverriddenBrowser(this.Request.Browser.IsMobileDevice
                                        ? BrowserOverride.Mobile
                                        : BrowserOverride.Desktop);

The 51 degrees framework will automatically do that, so you don’t really have to do this, but it can come in handy when you want to force it for some reason.

The Browser object has a lot more useful properties for determining which view to display, for instance the property Platform.

Creating Display Modes

As described above, the Browser object has a lot of information about the requested device.
At application start, we can create specific display modes for device types. For instance for Andriod devices:

DisplayModes.Modes.Insert(0, new DefaultDisplayMode("android")
{
    ContextCondition = Context => Context.Request.Browser.Platform == "Android"
});

Keep it clean and create a (static) class in the App_start folder called DisplayModes which contains a method RegisterDisplayModes which registers all display Modes:

public class DisplayModes
{
    public static void RegisterDisplayModes(DisplayModeProvider displayModeProvider)
    {
        displayModeProvider.Modes.Insert(0, new DefaultDisplayMode("android")
        {
            ContextCondition = Context => Context.Request.Browser.Platform == "Android"
        });
        .....
    }
}

Now call this method from the App_Start in the Global.asax file:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    DisplayModes.RegisterDisplayModes(DisplayModeProvider.Instance);
    .....
}

Now that we have registered a display mode for android, we can create android specific views.

Know that the first matching DisplayMode will be used. So the order of registration is very important! The mobile display mode is already registered.

Mobile views

Let’s make some mobile views now.

Creating views for devices is really simple, just add the name of the view before the extension of the file and the ViewEngine will automatically pick up the view for the correct device.

mobile-views

This example has a default Index view (index.cshtml) a mobile view for all mobile devices (Index.mobile.cshtml) and a android specific view (Index.android.cshtml).

This works for all views, including layouts, partial views, shared views, strongly typed views etc.

Because we registered the android DisplayMode at position 0 (first), all android devices will be provided with this view.  When the device is not an android device, but is a mobile device, the mobile view will be presented. For all other devices, the normal index view will be displayed.

Testing

It’s kinda difficult to test this from your developer laptop/pc, but there are many tools who simulate mobile devices. I like the mobile emulator from Opera. It has a lot of presets for mobile devices.

But there are many other emulators, even microsoft has its own.

Caching issues MVC 4

Now that you have created and published your mobile friendly application, you deploy it to your server and quickly check it on your mobile to see if it really works. And it works! Hooray!

Soon people start complaining about seeing strange views. It looks like a mixture of mobile and default views.

This is because of a bug in MVC4. The MVC team has released a patch for it, available here on NuGet.

The following two tabs change content below.
I'm a software developer from Utrecht. Interested in DDD, continuous delivery, new technologies & frameworks.

Latest posts by Vincent Keizer (see all)

Leave a Reply

Your email address will not be published. Required fields are marked *