This site uses cookies for analytics, personalized content and ads. By continuing to browse this site, you agree to this use. Learn more
Microsoft Logo
Gray Pipe
  • Developer Network
    • Downloads
      • Visual Studio
      • SDKs
      • Trial software
    • Programs
      • Subscriptions
      • Students
      • ISV
      • Startups
      • Events
    • Community
      • Magazine
      • Forums
      • Blogs
      • Channel 9
    • Documentation
      • APIs and reference
      • Dev centers
      • Samples
      • Retired content
Developer Network Developer
MSDN subscriptions
Get tools
magazine
  • Issues and downloads
    • All issues
    • 2019
      • February 2019
      • January 2019
    • 2018
      • Connect(); 2018
      • December 2018
      • November 2018
      • October 2018
      • September 2018
      • August 2018
      • July 2018
      • June 2018
      • May 2018
      • April 2018
      • March 2018
      • February 2018
      • January 2018
    • 2017
      • Connect(); 2017
      • December 2017
      • November 2017
      • October 2017
      • September 2017
      • August 2017
      • July 2017
      • June 2017
      • May 2017
      • April 2017
      • March 2017
      • February 2017
      • January 2017
    • 2016
      • December 2016
      • Connect(); 2016
      • November 2016
      • October 2016
      • September 2016
      • August 2016
      • July 2016
      • June 2016
      • May 2016
      • April 2016
      • March 2016
      • February 2016
      • January 2016
    • 2015
      • December 2015
      • November 2015
      • Windows 10 issue
      • October 2015
      • September 2015
      • August 2015
      • July 2015
      • June 2015
      • May 2015
      • April 2015
      • March 2015
      • February 2015
      • January 2015
    • 2014
      • Special 2014
      • December 2014
      • November 2014
      • October 2014
      • September 2014
      • August 2014
      • July 2014
      • June 2014
      • May 2014
      • April 2014
      • March 2014
      • February 2014
      • January 2014
    • 2013
      • Government 2013
      • December 2013
      • November 2013
      • October 2013
      • September 2013
      • August 2013
      • July 2013
      • June 2013
      • May 2013
      • April 2013
      • March 2013
      • February 2013
      • January 2013
    • 2012
      • December 2012
      • November 2012
      • Windows 8
      • October 2012
      • September 2012
      • August 2012
      • July 2012
      • June 2012
      • May 2012
      • April 2012
      • March 2012
      • February 2012
      • January 2012
    • 2011
      • December 2011
      • November 2011
      • October 2011
      • September 2011
      • August 2011
      • July 2011
      • June 2011
      • May 2011
      • April 2011
      • March 2011
      • February 2011
      • January 2011
    • 2010
      • December 2010
      • November 2010
      • October 2010
      • September 2010
      • August 2010
      • July 2010
      • June 2010
      • May 2010
      • April 2010
      • March 2010
      • February 2010
      • January 2010
    • 2009
      • December 2009
      • November 2009
      • October 2009
      • September 2009
      • August 2009
      • July 2009
      • June 2009
      • May 2009
      • April 2009
      • March 2009
      • February 2009
      • January 2009
  • Subscribe
  • Submit article
search clear
We’re sorry. The content you requested has been removed. You’ll be auto redirected in 1 second.
Issues and downloads 2013 July 2013 Cutting Edge - Creating Mobile-Optimized Views in ASP.NET MVC 4

July 2013
Volume 28 Number 7

Cutting Edge - Creating Mobile-Optimized Views in ASP.NET MVC 4

By Dino Esposito | July 2013

Dino EspositoIf you scratch the surface of common-sense considerations about programming mobile sites, you find an inherent contradiction. On one hand, you hear people screaming about being (or willing to be) mobile-first in their approach to programming applications and sites. On the other hand, you often hear the same people praise CSS media queries and liquid layouts. The contradiction I see is that the common use being made of CSS media queries and liquid layouts doesn’t put the mobile perspective before everything—it’s not a mobile-first technique. In this article I’ll explain how to use server-side logic to offer up the best display for a given device, incorporating a new feature of ASP.NET MVC 4 called display modes.

The problem isn’t CSS media queries as a technology. The problem isn’t even responsive Web design (RWD) as the supporting methodology of CSS media queries—if not the technology’s inspiring philosophy. So what makes the use of CSS media queries and liquid layouts a “mobile-last” approach? A clue can be found right in the slogan used to push this approach: A single codebase can serve multiple views. In this perspective, CSS—a client-side technology—is used to switch between views, and JavaScript is used to adapt views further when CSS isn’t enough.

As I see things, in this approach there’s the underlying proposition of serving all devices the same content, just adjusting the page layout to fit the screen size. In doing so, you might not be able to offer the best possible experience to users. I believe you reasonably should aim at having a single codebase—a common ground of Web APIs—but should definitely focus on specific use cases for each class of devices you intend to support. The term “mobile” makes little sense today, as it’s being replaced by classes of devices such as smartphones, tablets, laptops and smart TVs—not to mention wearable devices such as eyeglass displays and smart wristwatches.

About a year ago, I presented in this column a server-side approach to take with ASP.NET MVC site development: to build ad hoc views for each class of supported devices (“Mobile Site Development: Markup,” msdn.microsoft.com/magazine/jj133814). I did that in the context of ASP.NET MVC 3. Nicely enough, ASP.NET MVC 4 comes with the aforementioned display modes, which easily can be employed to implement server-side logic that intelligently serves the best view and content for a given device. To be really effective, this approach requires that you know as much as possible about the capabilities of the requesting device. However, besides basic information about the screen size and current orientation, there’s not much else that can be detected on the client. You then need to resort to a server repository of device information.

Introducing Display Modes in ASP.NET MVC 4

Before I start delving deep into display modes, let me state up front that this article (as well as display mode technology itself) is mainly concerned with building a new, unique site that dynamically binds the same URL to different views. If you already have a Web site and want to provide a companion site optimized for some (mobile) devices, well, that’s a different story. You can still use this column as a guide for building the companion site, but unifying URLs with an existing parent site requires different tools.

In ASP.NET MVC 4, display modes are a system feature that extends the classic behavior of view engines with the ability to pick the view file that’s most appropriate for the requesting device. In the aforementioned article for ASP.NET MVC 3, I used a custom view engine for this purpose. In that solution I also was limited to Razor views. With display modes, your controller methods will still invoke, say, a view named Index, and the ASP.NET MVC runtime will instead pick up a view file named index.mobile.cshtml if the requesting device is known to be a mobile device.

This is great news, as it means you can still have a single codebase for your site. You just need to add extra CSHTML view files for each class of device you intend to support. To start playing with display modes, let’s have a look at the code sample in Figure 1.

Figure 1 The Standard List of Supported Display Modes
XML
Copy
<h2>
  Display Modes currently active
  (@DisplayModeProvider.Instance.Modes.Count mode(s))
</h2>
<ul>
@{
  foreach(var d in DisplayModeProvider.Instance.Modes)
  {
    <li>@(String.IsNullOrEmpty(d.DisplayModeId)
      ?"default" :d.DisplayModeId)</li>
  }
}
</ul>

The page in the code in Figure 1 shows the standard list of supported display modes. Figure 2 shows the output generated by the page.

Default List of Display Modes
Figure 2 Default List of Display Modes

ASP.NET MVC 4 display modes follow a few conventions. In particular, each display mode is associated with a keyword. The keyword is used to compose the name of the corresponding view file. The default display mode is bound to an empty string. As a result, the following view files are correctly handled by any ASP.NET MVC 4 application without any further intervention from you: index.cshtml and index.mobile.cshtml.

To see a demo, copy the index.cshtml file to a new file named index.mobile.cshtml and add it to the project. To distinguish between the two files, add the following to the mobile file:

XML
Copy
<div style="border-bottom: solid 1px #000">Mobile view</div>

If you run the application and test it using Internet Explorer or another desktop browser, nothing changes. Try hitting F12 to bring up Internet Explorer Developer Tools and set a mobile user agent (UA) by selecting Tools | Change user agent string, as shown in Figure 3.

Forcing a Mobile User Agent into Internet Explorer for Testing Purposes
Figure 3 Forcing a Mobile User Agent into Internet Explorer for Testing Purposes

I’ve already configured a few mobile and tablet UAs. For example, you can use the following, which identifies the requesting browser as an HTC Desire Android smartphone:

XML
Copy
Mozilla/5.0 (Linux; U; Android 2.1; xx-xx; HTC Desire Build/ERE27)
AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2

Figure 4 shows what you get from the ASP.NET MVC 4 site. The page being served from the same pair of controller and action methods is index.mobile.cshtml. More important, all of this took place without any change in the programming style and without learning any new skills.

Switching to a Mobile View
Figure 4 Switching to a Mobile View

Going Beyond the Basics

What’s been discussed so far is the bare minimum of what you can—and should—do in your mobile site development. Two key points need to be addressed to turn display modes into a solution for a realistic site. One is exploring ways to add multiple display modes. The other is exploring ways to inject some ad hoc logic to detect devices more reliably.

The built-in logic used by ASP.NET MVC to detect mobile devices isn’t all that reliable. It probably works with most smartphones, but it fails with older cell phones. For example, consider the following UA:

XML
Copy
SAMSUNG-GT-S3370/S3370DDJD4 SHP/VPP/R5 Dolfin/1.5 Qtv/5.3
SMM-MMS/1.2.0 profile/MIDP-2.1 configuration/CLDC-1.1 OPN-N

This UA refers to a legacy phone (fairly popular a couple years ago) running a proprietary OS and a WebKit-based custom browser. The phone doesn’t support Wi-Fi connectivity, but it does have surprisingly good HTML-rendering capabilities. The screen is tinier than most smartphones, but it’s touch-enabled. With the basic display mode support from ASP.NET MVC, this phone isn’t recognized as a mobile device and is served the full versions of pages. This has two drawbacks. First, users can hardly view content because it will be stretched and wrapped around the screen. Second, a lot of content will be downloaded, and because the phone doesn’t support Wi-Fi connectivity, all of this likely happens on a 3G connection—certainly slow and possibly expensive for the user.

When I raise this point, some people reply that their sites just don’t support these types of legacy phones. That’s perfectly sound, but wouldn’t it be nice to send a polite message to the user in that case instead of letting things go uncontrolled? To be able to send a message such as, “Sorry, the site can’t be viewed on your device,” you still need to recognize the device properly and understand that it’s different from, say, an iPhone. Furthermore, whether you can safely ignore legacy devices is a business—not implementation—decision. Not serving older generations of devices could affect your business beyond imagination. So, let’s see how to add multiple display modes to a site to properly serve multiple classes of devices.

Classes of Devices

A modern Web site offers the best possible experience regardless of the device type. “Best possible experience” means providing ad hoc use cases, selected data and specific functions. The resulting markup has to be device-specific. If you adjust things on the client, instead—as happens when you rely on CSS media queries—you actually have a unified vision of the pages and then just adapt them to tinier screens. This mostly means hiding some blocks, flowing some others vertically and perhaps requesting a lighter set of visuals. The unified vision of the page is often the desktop page. Personally, I wouldn’t call this a mobile-first approach.

By saying “device type,” I don’t mean distinguishing an iPhone device from a Windows Phone device. Rather, I aim to use logic that can serve different markup to smartphones, tablets and laptops. So in ASP.NET MVC 4, I’d have at least three display modes: smartphone, tablet and default (for desktop browsers). I’ll add a new DisplayConfig class to be invoked in App_Start (see Figure 5).

Figure 5 The DisplayConfig Class
XML
Copy
public class DisplayConfig
{
  public static void RegisterDisplayModes(IList<IDisplayMode> displayModes)
  {
    var modeDesktop = new DefaultDisplayMode("")
   {
     ContextCondition = (c => c.Request.IsDesktop())
   };
   var modeSmartphone = new DefaultDisplayMode("smart")
   {
     ContextCondition = (c => c.Request.IsSmartphone())
   };
   var modeTablet = new DefaultDisplayMode("tablet")
   {
     ContextCondition = (c => c.Request.IsTablet())
   };
   displayModes.Clear();
   displayModes.Add(modeSmartphone);
   displayModes.Add(modeTablet);
   displayModes.Add(modeDesktop);
 }
}

The class first empties the provided collection of display modes. In this way, it gets rid of default modes. Next, the code fills up the provided system collection with a newly created list of display modes. A new display mode is an instance of the DefaultDisplayMode class. The name of the mode is set through the constructor. The logic that determines whether a given UA is matched is set through the property ContextCondition.

The ContextCondition property is a delegate that accepts an HttpContextBase object and returns a Boolean. The body of the delegate is all about snooping into the HTTP context of the current request in order to determine whether the given display mode is appropriate. In Figure 5, I use a few extension methods to keep code highly readable. Figure 6 lists those extensions methods.

Figure 6 Extension Methods to Keep Code Clear
XML
Copy
public static class HttpRequestBaseExtensions
{
  public static Boolean IsDesktop(this HttpRequestBase request)
  {
    return true;
  }
  public static Boolean IsSmartphone(this HttpRequestBase request)
  {
    return IsSmartPhoneInternal(request.UserAgent);
  }
  public static Boolean IsTablet(this HttpRequestBase request)
  {
    return IsTabletInternal(request.UserAgent);
  }
  // More code here.
}

All the code discussed so far is pure infrastructure. You end up with one method to write for each display mode. Each method takes a UA and must return a Boolean answer. Here’s a very basic routine to check for tablets:

XML
Copy
private static Boolean IsTabletInternal(String userAgent)
{
  var ua = userAgent.ToLower();
  return ua.Contains("ipad") || ua.Contains("gt-");
}

This routine is only guaranteed to successfully detect iPad and Galaxy Tab devices, but you can see the point about how these context condition routines should be written. You might want to add more code to check for smartphones, at the very least. To detect tablets and smartphones, you can take advantage of any open source or commercial Device Description Repository (DDR) framework. I’ll discuss that in more detail in my next column.

Serious Business

A server-side approach to mobile sites may not always be necessary, but it’s a serious matter whenever there’s some business behind the site. I wouldn’t recommend a server-side approach for, say, a conference site or any sort of short-lived site. However, a business site aimed at the largest possible audience needs to emphasize optimization for devices beyond just plain rendering for mobile.

On the client, you’re limited to browser window size and orientation, and you can’t check the OS or touch capabilities—or check for more advanced things such as whether the device supports wireless, streaming, inline images, SMS and more. Display modes make it particularly easy to implement a multi-view approach in  ASP.NET MVC 4.

In my next column I’ll cap off my argument by showing how to integrate the DDR used by Facebook—Wireless Universal Resource File (WURFL)—with ASP.NET MVC 4.


Dino Esposito is the author of “Architecting Mobile Solutions for the Enterprise” (Microsoft Press, 2012) and “Programming ASP.NET MVC 3” (Microsoft Press, 2011), and coauthor of “Microsoft .NET: Architecting Applications for the Enterprise” (Microsoft Press, 2008). Based in Italy, Esposito is a frequent speaker at industry events worldwide. Follow him on Twitter at twitter.com/despos.

Thanks to the following technical expert for reviewing this article: Mani Subramanian (Microsoft)
Mani Subramanian has been involved in development and testing of software projects for the past 12 years with a focus on SOA, cloud computing and core.net.

 

MSDN Magazine Blog

 

More MSDN Magazine Blog entries >


Current Issue


February 2019

Browse All MSDN Magazines


Subscribe to MSDN Flash newsletter


Receive the MSDN Flash e-mail newsletter every other week, with news and information personalized to your interests and areas of focus.

Follow us
  • https://www.facebook.com/microsoftdeveloper
  • https://twitter.com/msdev
  • https://plus.google.com/111221966647232053570/
Sign up for the MSDN Newsletter
Is this page helpful?
Your feedback about this content is important.
Let us know what you think.
Additional feedback?
1500 characters remaining
Thank you!
We appreciate your feedback.

Dev centers

  • Windows
  • Office
  • Visual Studio
  • Microsoft Azure
  • More...

Learning resources

  • Microsoft Virtual Academy
  • Channel 9
  • MSDN Magazine

Community

  • Forums
  • Blogs
  • Codeplex

Support

  • Self support

Programs

  • BizSpark (for startups)
  • Microsoft Imagine (for students)
United Kingdom (English)
  • Newsletter
  • Privacy & cookies
  • Terms of use
  • Trademarks
logo © 2019 Microsoft