Chapter 27

Developing Websites with Mobile in Mind

WHAT’S IN THIS CHAPTER?

WROX.COM CODE DOWNLOADS FOR THIS CHAPTER

Please note that all the code examples in this chapter are available as a part of this chapter’s code download on the book’s website at www.wrox.com on the Download Code tab.

Today, having a successful website means making it accessible to mobile devices. The number of mobile phones that are capable of browsing the Internet continues to grow, as does the number of people using them to do just that. It is no longer safe to assume that a particular website won’t be browsed with a mobile device. For many businesses, having a mobile website is the source of an increasing percentage of their revenue. Even for businesses that don’t rely on mobile traffic for income, their customers are beginning to expect the ability to browse their site on a mobile device. As mobile usage continues to rise, mobile web design becomes more important than ever.

This chapter looks at various techniques and technologies that make it easier to accommodate mobile devices. While ASP.NET provides tools to help, not all solutions depend on a particular technology.


THE ORIGINS OF WIRELESS MARKUP LANGUAGE
Although mobile design has changed considerably over the years, the concept of developing a mobile website is nothing new. As a matter of fact, Wireless Markup Language (WML), an XML-based language designed specifically for developing websites for mobile devices, was developed in 1998. Microsoft created a set of mobile controls for ASP.NET as early as version 2 of the .NET Framework. The controls in the System.Web.UI.MobileControls namespace produced WML, CHTML, or HTML based on the browser. The namespace was marked obsolete in version 4 of the .NET Framework in favor of more current mobile web development standards. Visual Studio 2010 and ASP.NET MVC introduced a set of tools to make developing mobile websites much easier. Visual Studio 2012 and the latest version of ASP.NET MVC continue to enhance the tools available for mobile web development and make it easier than ever to build mobile sites.

FACING MOBILE WEB DESIGN CHALLENGES

Although the tools and technology for developing mobile websites has changed, the challenges remain the same and they are as follows:

The challenges facing mobile web developers don’t end with these. But they are representative of the kinds of challenges presented when developing websites for mobile devices. Overcoming these challenges often comes from experience, both good and bad. Tools like those in Visual Studio 2012, version 4.5 of the .NET Framework, and the latest version of ASP.NET MVC definitely make it easier.

RESPONSIVE DESIGN AND ADAPTIVE DESIGN

Designing sites for mobile browsers is no longer the exception. It is the rule. Most successful websites now have explicit support for mobile browsers. As with most technologies or techniques that become a mainstream, the amount of terminology surrounding them can become confusing. Perhaps you have heard terms such as responsive design, progressive enhancement, and adaptive design. What is the difference between them?

These terms are often used in conjunction with one another. A technique that is an example of responsive design may also be an example of progressive enhancement and vice versa. Two of the techniques used in responsive design involve including the viewport meta tag and utilizing CSS media queries. Utilizing CSS media queries can also be used in progressive enhancement.

Modifying the Viewport

When a browser renders a website, it does so in a viewport. A viewport is simply the area available for viewing a website. When you browse a website using a mobile browser, the browser, by default, assumes that you’re viewing the website on a desktop. The browser assumes you want to see the entire site and not just one corner of it. It therefore sets the viewport width much larger than the physical screen width, causing the viewport displaying the entire site to be stuffed into the small display. To demonstrate this, create a new ASP.NET Empty Web Application project called HTMLMobile. Then create a new HTML page by right-clicking the project and selecting Add ⇒ New Item. Select Html Page and name it default.html. The content of the default.html page is shown in Listing 27-1 (file defaultbasic.html in the code download for this chapter).

LISTING 27-1: The default.html page

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Responsive Design Example</title>
    <style>
        header{ background-color: #808080; }
        footer{
            background-color: #808080;
            text-align: left;
            height: 50px;
            clear: both;
        }
        nav{ text-align:left; }
        nav a{
            padding-left: 10px;
            padding-right: 10px;
            color: black;
        }
        #content{
            padding-left: 10px;
            border-right: 1px solid black;
            width: 45%;
            float: left;
        }
        #news{
            padding-left: 10px;
            width: 45%;
            float: left;
        }
    </style>
</head>
<body>
    <header>
        <nav>
            <a href="#">Home</a>
            <a href="#">Page 1</a>
            <a href="#">Page 2</a>
            <a href="#">About</a>
        </nav>
    </header>
    <div id="content">
        <h1>Welcome!</h1>
        Welcome to responsive design example.
    </div>
    <div id="news">
        <h2>News</h2>
        Breaking news!
    </div>
    <footer>
        Copyright &copy; Examples By U
    </footer>
</body>
</html>

It is easy to see the effect of the viewport by browsing to the page using a mobile browser. Figure 27-1 shows the default.html page viewed in a mobile browser.

FIGURE 27-1

image

You can see that the browser has rendered the page as though it were on a larger screen and then shrunk it to fit in the mobile browser screen. Many of the elements on the screen are too small to read, much less interact with. To fix the problem, you need to tell the browser to use a viewport that is the same size as the device screen width. You do this by adding the Viewport Meta tag between the opening and closing head tag. Listing 27-2 (file defaultviewport.html in the code download for this chapter) shows a part of the default.html file after adding the Viewport Meta tag.

LISTING 27-2: Default page with Viewport Meta tag

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Responsive Design Example</title>
    <meta name="viewport" content="width=device-width" />
    <style>
        header
        {
            background-color: #808080;
        }

Figure 27-2 shows the page displayed in a mobile browser after adding the Viewport Meta tag.

FIGURE 27-2

image

It is easy to see that the Viewport Meta tag has done the job. Now the content of the site is more readable. But you can see a new problem starting to present itself. Although the content is not too small, the layout of the page does not really suit the smaller screen. Elements on the page are beginning to overlap. The scale of the site is correct, but now the layout needs to be made more responsive to screen size.

Using CSS Media Queries

Forcing the browser to scale its contents based on the size of the screen is a first step. But most of the time, a layout designed for a larger screen may not be appropriate for a smaller one. If the layout of the page has been designed to use CSS, the layout can be changed using different CSS. The question is how you tell the browser to use different CSS for different sizes of screens. The answer is by using CSS media queries.

CSS media queries enable you to target CSS rules at particular display features. Targeting media types such as “screen” and “print” with CSS rules has been available since HTML4 and CSS2. However, media queries extend this functionality to include other conditions. A media query consists of a media type and zero or more expressions that check for the conditions of particular media features. Some of the media features that you can use are “width,” “height,” and “color.” When targeting different screen sizes, the most common is “width.” Though you can use other conditions, typical conditions are min-width and max-width.

It is possible to implement progressive enhancement using CSS media queries. It may not always be possible to adopt the practice of progressive enhancement. At times, especially when adding mobile capabilities to an existing website, your starting point is already set. However, in this example you can modify the layout of the site to target, by default, the lowest common denominator, which is a mobile browser. Then, using CSS media queries, you can add additional style rules to provide a different layout for more accommodating screen sizes. Listing 27-3, shown in file defaultqueries.html in the code download for this chapter, shows the style block after making changes to target, by default, a mobile browser, and then progressively larger screens.

LISTING 27-3: The style block after adding CSS Media Queries

<style>
    header{ background-color: #808080; }
    footer{
        background-color: #808080;
        text-align: center;
        height: 50px;
    }
    nav{ text-align:center; }
    nav a{
        display: block;
        padding-left: 10px;
        padding-right: 10px;
        color: black;
    }
    #content{ padding-left: 10px; }
    #news{ padding-left: 10px; }
    @media screen and (min-width: 601px)
    {
        footer{ clear: both; }
        nav a{ display: inline; }
        #content{
            border-right: 1px solid black;
            width: 45%;
            float: left;
        }
        #news{
            width: 45%;
            float: left;
        }
    }
    @media screen and (min-width: 901px)
    {
        footer{ text-align: left; }
        nav{ text-align: left; }
    }
</style>

For the preceding code, the first set of style rules are applied as the base set of rules targeting a mobile browser. Notice the nav and footer elements have been changed to specify the text to be centered and the anchor elements have a display value of block. The content and news divs have also had their float values removed, thus stacking them vertically instead of horizontally. Elements presented vertically are often more appropriate in a mobile browser than horizontally because horizontal space is limited.

A media query defines a block of style rules that are applied only if the media type is screen and the minimum width of the screen is 601px. A screen width of 601px to 900px will accommodate many tablet devices. Notice the style rules in this block replace many of the layout styles that were removed from those targeting the lowest common denominator, the mobile browser:

@media screen and (min-width: 601px)

Another media query defines a block of style rules that are applied only if the media type is screen and the minimum width of the screen is 901px. Because many tablet devices utilize a screen width up to 900px, the rules defined in this block accommodate larger screen sizes, such as a desktop. When the following media query is applied, you just left justify the menu items and the footer text. Although this may seem trivial, it demonstrates multiple levels of progressive enhancement.

@media screen and (min-width: 901px)

Figure 27-3 shows the page displayed in a mobile browser. For contrast, Figure 27-4 shows the same page displayed in a desktop browser.

FIGURE 27-3

image

FIGURE 27-4

image

ASP.NET MOBILE APPLICATIONS

Targeting your ASP.NET applications to mobile devices involves changes on both the client and the server. Choosing to do just one or the other does not provide a complete solution. This is an area of much debate in mobile web development. Some believe that the content in an application should be the same, whether viewed from a desktop or a mobile device. In these cases, the only things that change when users view content from a mobile device is simply the layout of the content and perhaps the styling of the elements used to present it. This is a responsive web design approach. Still others believe that the mobile user may not need to see the same content, or at least not as much of it. In these cases, the differences between viewing on a desktop and a mobile device are more extensive.

Only making client changes, such as those for responsive design, allows your application to scale better to the size of the mobile device screen. Your application can then respond to changes in orientation. It can provide layout and styling options more suited to the size of the device on which it’s viewed. However, attempting to accommodate all potential devices with a single page may mean including unnecessary markup, CSS, and JavaScript, thus increasing required bandwidth.

Making the changes on the server involves providing dedicated pages to be served to mobile devices. This may cause some duplication of effort and code, but it also allows for ultimate control of what the user sees in both a desktop browser and a mobile browser. When taking a more server-centric approach, you must take care to encapsulate common logic and functionality into libraries that can be shared between the two different versions of a page.

If you have read this chapter from the beginning, you’re already familiar with the kinds of changes you can make in the client code to create more mobile-friendly pages. This section focuses on a server-centric approach to building mobile applications.

You can start by creating a new ASP.NET Web Forms Application and calling it WebFormsMobile.

Detecting Mobile Browsers and Devices

The first hurdle to overcome is determining how to detect the characteristics of the browser that views your application. Knowing information about the browser is necessary if you are going to make decisions on the server based on this information. Luckily, ASP.NET provides the Request.Browser object, which retrieves information about the characteristics of the browser in use. Although the Request.Browser object has many interesting and helpful properties, three are specifically targeted toward mobile browsers:

Serving Mobile Master Pages

Now that you have the means to detect the capabilities of the browser requesting a page, you can use that to serve mobile-specific pages to mobile browsers. It may be possible to handle the differences between mobile pages and standard pages simply through the use of a mobile-specific master page. Create a new master page in the root of your application by right-clicking the project and selecting Add ⇒ New Item. Choose Master Page from the Add New Item dialog box and name it MobileSite.Master. You’ll create a simplified version of the standard master file for use with mobile devices. Listing 27-4 presents the code for the C# version of the MobileSite.Master file. You can find this code in file MobileSite.Master located in the root of the WebFormsMobileCS or WebFormsMobileVB projects in the code download for this chapter.

LISTING 27-4: MobileSite.Master file

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="MobileSite.master.cs"
    Inherits="WebFormMobile.MobileSite" %>
 
<!DOCTYPE html>
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
    <meta name="viewport" content="width=device-width" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        This is a mobile browser!
 
        <asp:ContentPlaceHolder ID="FeaturedContent" runat="server">
        </asp:ContentPlaceHolder>
 
        <asp:ContentPlaceHolder ID="MainContent" runat="server">
        </asp:ContentPlaceHolder>
    </div>
    </form>
</body>
</html>

Having created a simplified mobile version of the master page, you have to instruct any page displaying in a mobile browser to use the MobileSite.Master master page. To do this, override the Page_PreInit handler of each page and change the master page that it is set to use. You can start by modifying the default page in the project to use the MobileSite.Master when users view it in a mobile browser. Listing 27-5 shows the default page code-behind after you override the Page_PreInit handler to change the master page if it’s viewed on a mobile device. You can find the code for this listing in files Default.aspx.cs and Default.aspx.vb located in the root of the WebFormsMobileCS or WebFormsMobileVB projects in the code download for this chapter.

LISTING 27-5: Default code-behind with overridden Page_PreInit

VB

Public Class _Default
    Inherits Page
 
    Protected Overrides Sub OnPreInit(e As EventArgs)
        If Request.Browser.IsMobileDevice Then
            MasterPageFile = "~/MobileSite.Master"
        End If
 
        MyBase.OnPreInit(e)
    End Sub
 
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles 
        Me.Load
 
    End Sub
End Class

C#

using System;
using System.Web.UI;
 
namespace WebFormMobile
{
    public partial class _Default : Page
    {
        protected void Page_PreInit(object sender, EventArgs e)
        {
            if (Request.Browser.IsMobileDevice)
                MasterPageFile = "~/MobileSite.Master";
        }
 
        protected void Page_Load(object sender, EventArgs e)
        {
 
        }
    }
}

Executing the application and viewing it in a mobile browser produces the results shown in Figure 27-5.

FIGURE 27-5

image

Creating Mobile Web Forms

You may have a need for more changes than modifying the master page can provide. For example, you may need to more dramatically alter the content that is provided to a mobile browser. If that is the case, you can provide a parallel set of pages that are designed specifically for viewing in mobile browsers. Although this does introduce some duplication of code, it also supplies a dedicated set of pages that only mobile browsers can target. For each standard page in the application that would be available to a mobile browser, you build a mobile-specific version. To do this, create a folder at the root of the application named Mobile. Then create a new Web Form in this folder named Default.aspx. This Web Form will be the mobile-specific version of the standard default web form located in the root folder. To keep the example fairly manageable, you won’t include any styles or scripts, just some simple content. The content for the C# version of the new Default.aspx file is shown in Listing 27-6 (file /Mobile/Default.aspx in the code download for this chapter).

LISTING 27-6: Mobile-specific Default.aspx

<%@ Page Language="C#" MasterPageFile="~/MobileSite.Master" AutoEventWireup="true" 
    CodeBehind="Default.aspx.cs" Inherits="WebFormMobile.Mobile.Default" %>
 
<asp:Content runat="server" ID="FeaturedContent" 
    ContentPlaceHolderID="FeaturedContent">
    <p>
        Welcome to the Mobile version of the site!
    </p>
</asp:Content>
 
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
    <p>
        This is a mobile version of the site!
    </p>
</asp:Content>

If you replicate all the standard web forms including their relative folders in the Mobile folder you created, it makes redirecting mobile browsers much easier. You only have to redirect the first request for a standard web form to the equivalent web form in the Mobile folder. Subsequent requests utilize relative paths in the Mobile folder and do not need further redirection. Additionally, if you want to give the users the capability to switch to the standard desktop version of the application on their mobile browser, you simply provide a link back to the standard version of the web form. Again, relative paths keep subsequent requests all in the standard web form folder structure.

The initial redirect for a mobile browser to the Mobile folder structure can occur upon the start of the browsing session. Add a handler for the Session_Start event in the Global.asax.cs or Global.asax.vb file depending on the application language. Listing 27-7 shows the code for the Session_Start handler. You can find the code for this listing in code file Global.asax.cs and Global.asax.vb located in the root of the WebFormsMobileCS or WebFormsMobileVB projects in the code download for this chapter.

LISTING 27-7: Session_Start handler in the Global.asax file

VB

    Sub Session_Start(sender As Object, e As EventArgs)
        Dim httpRequest As HttpRequest = HttpContext.Current.Request
        If httpRequest.Browser.IsMobileDevice Then
            Dim path As String = httpRequest.Url.PathAndQuery
            Dim isOnMobilePage As Boolean = path.StartsWith("/Mobile/", 
                StringComparison.OrdinalIgnoreCase)
            If Not isOnMobilePage Then
                Dim redirectTo As String = "~/Mobile/"
                HttpContext.Current.Response.Redirect(redirectTo)
            End If
        End If
    End Sub

C#

void Session_Start(object sender, EventArgs e)
{
    HttpRequest httpRequest = HttpContext.Current.Request;
    if (httpRequest.Browser.IsMobileDevice)
    {
        string path = httpRequest.Url.PathAndQuery;
        bool isOnMobilePage = path.StartsWith("/Mobile/", 
                               StringComparison.OrdinalIgnoreCase);
        if (!isOnMobilePage)
        {
            string redirectTo = "~/Mobile/";
 
            HttpContext.Current.Response.Redirect(redirectTo);
        }
    }
}

If you execute the application and browse to the root of the site you will see the new default page in the Mobile folder instead of the standard default page. Figure 27-6 shows the mobile browser being forwarded to the mobile-specific default page.

FIGURE 27-6

image

Friendly URLs in ASP.NET Web Forms

Routing in ASP.NET Web Applications provides a way to give the user a URL that is easier to remember and understand. However creating routes and managing route tables can take some time to understand. A new ASP.NET feature called FriendlyUrls makes routing easier and URLs cleaner.

FriendlyUrls is included in the Visual Studio 2012.2 update. But it is also available for C# projects as a NuGet package. The name of the NuGet package is Microsoft.AspNet.FriendlyUrls. To install the NuGet package in our WebFormsMobileCS project, you can use the NuGet Package Manager, which is installed by default in Visual Studio 2012. Open the Package Manager Console by clicking on Tools ⇒ Library Package Manager ⇒ Package Manager Console from the Visual Studio menu. At the console prompt, run the command:

Install-Package Microsoft.AspNet.FriendlyUrls

When you install the FriendlyUrls NuGet package, a RouteConfig.cs file will be added to the App_Start folder in the root of the Web application. You will need to add one line of code to the Application_Start handler in the Global.asax file located in the root of the web application. Add the following line to the Application_Start handler:

RouteConfig.RegisterRoutes(RouteTable.Routes);

Now if you execute the application, you can browse to any .aspx page without specifying the extension. For example, in order to browse to the Contact.aspx page, you can simply specify Contact in the URL without the extension and FriendlyUrls will look for a file called Contact.aspx. Figure 27-7 shows the Contact.aspx page rendered in a mobile browser by only specifying Contact in the URL.

FIGURE 27-7

image

Using the FriendlyUrlSettings object, you can also instruct ASP.NET to automatically strip the extensions from pages in the URL. When you are working with an existing project like the WebFormsMobileCS project, you don’t want to have to go through every Web Form in the project and modify every link and URL to remove the .aspx extension. You can have ASP.NET FriendlyUrls do it for you. Open the RouteConfig.cs file in the App_Start folder. This is the file that was added by the FriendlyUrls Nuget package. Change

routes.EnableFriendlyUrls();

to

FriendlyUrlSettings settings = new FriendlyUrlSettings();
            settings.AutoRedirectMode = RedirectMode.Permanent;
            routes.EnableFriendlyUrls(settings);

After making this change, execute the application and browse to the Contact.aspx Web Form. ASP.NET turns the GET request for /Contact.aspx into a 301 redirect to /Contact.

ASP.NET MVC 4 MOBILE APPLICATIONS

ASP.NET MVC (MVC) is a framework for building standards-based web applications that are easily scalable and testable. It uses the well-established Model-View-Controller design pattern. In MVC 3, a set of features were introduced to make mobile web development easier. Even with these features, it is increasingly difficult to provide a consistent experience on so many different mobile browsers and platforms. MVC 4 enhances and adds to the features originally introduced in version 3. These additions aim to make it even easier to develop a consistent mobile experience across more devices and browsers.

Adaptive Rendering in ASP.NET MVC 4

The Visual Studio project templates in version 4 of the MVC framework include many changes from version 3, not the least of which is the overall visual design. Even if you are going to use the design that the new templates offer, the more interesting change is the inclusion elements that provide adaptive rendering. The use of the viewport meta tag and CSS Media Queries allow these new templates to provide better scaling of your pages and a modified layout for smaller screen sizes. Figure 27-8 shows the default MVC 3 template in a mobile browser and Figure 27-9 shows the default MVC 4 template in a mobile browser. Ignoring the fact that the template design is different, the scaling difference in the two templates is obvious. The MVC 3 template attempts to render the page as though it were in a desktop browser scaled to the size of the Windows Phone screen. The MVC 4 template uses adaptive rendering to render the page at a scale more appropriate for the screen size. What you can’t see from these two figures is that the MVC 4 template also modifies the page layout to better present the page material on a smaller screen.

FIGURE 27-8

image

FIGURE 27-9

image

To see the new adaptive rendering elements provided in these new templates, you can create an MVC project. Begin by creating a new project in Visual Studio called MvcMobile. Select .NET 4.5 Framework as the target framework and the ASP.NET MVC 4 Web Application project type. Due to the number of templates available when creating a new MVC Web Application, this is a two-step process. Selecting an ASP.NET MVC 4 Web Application doesn’t immediately create the web application. You must select the particular type of MVC 4 application template you would like to use. After you select the ASP.NET MVC 4 Web Application, a template selection dialog box is displayed. Select the Internet Application template. Figure 27-10 shows the New ASP.NET MVC 4 Project dialog box with the correct selections made.

FIGURE 27-10

image

Working with Viewport Meta Tags

If you read the earlier section of this chapter on responsive design, you will be familiar with the viewport meta tag used to instruct the browser to take into account the physical size of the browser viewing area when displaying a web page. The Internet, Intranet, and Mobile Application templates shown in Figure 27-10 include a default Layout file. The Layout file already contains the viewport Meta tag. Listing 27-8 shows part of the C# version of the layout file that is included in the project when using the Internet Application template. The layout file is located in the \Views\Shared folder off of the root of the project. You can find the code for this listing in files _Layout.cshtml and _Layout.vbhtml in the code download for this chapter.

LISTING 27-8: The default Layout file in an MVC 4 application

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>@ViewBag.Title - My ASP.NET MVC Application</title>
        <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <meta name="viewport" content="width=device-width" />
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>
        <header>
            <div class="content-wrapper">
                <div class="float-left">
                    <p class="site-title">
                    @Html.ActionLink("your logo here", "Index" "Home")
                    </p>
                </div>

The viewport meta tag in the head section of the page instructs the browser to use the width of the device screen as the page layout width:

<meta name="viewport" content="width=device-width" />

Working with CSS Media Queries

One of the other concepts covered in the responsive design section of this chapter is CSS media queries. CSS media queries are used to limit the scope of style sheets by using media features, such as width, height, and color. The Internet, Intranet, and Mobile Application templates shown in Figure 27-10 also include a default CSS file named Site.css. The CSS file includes many default style rules and includes another set of style rules that are filtered, or limited, by a CSS media query. Listing 27-9 (file \Content\Site.css in the code download for this chapter) shows a portion of this Site.css file containing the CSS media query.

LISTING 27-9: The CSS media query in the Site.css file

/********************
*   Mobile Styles   *
********************/
@media only screen and (max-width: 850px) {
 
    /* header
    ----------------------------------------------------------*/
    header .float-left,
    header .float-right {
        float: none;
    }
 
    /* logo */
    header .site-title {
        margin: 10px;
        text-align: center;
    }

You use a CSS media query to provide a set of style rules that alter the layout of the page based on the width of the browser screen. The media query dictates that the style rules included in the Mobile Styles section of the CSS file are not used unless the media type is only screen and the width is less than or equal to 850px:

@media only screen and (max-width: 850px)

Creating Mobile-Specific Views

Adaptive rendering enables you to modify the scaling and layout of CSS-styled elements on a page when it is viewed in various conditions, including smaller screens. However, you may want a more radical change to a page when it is viewed in a mobile browser. To do this, you provide one view for use by non-mobile browsers and one for use by mobile browsers only. Prior to MVC 4, you had to use browser-sniffing and ViewEngine overrides to determine which view to serve to the browser.

MVC 4 provides new functionality to enable you to override views served to mobile devices using a convention over configuration approach. This functionality is available to all views including Layouts. To provide a mobile-specific version of a view, you simply create a file using the naming convention [viewname].mobile.cshtml or [viewname].mobile.vbhtml. When ASP.NET MVC 4 services a request from a mobile browser, it first looks for a file following this alternate mobile naming convention. If it does not find one, it falls back to the standard view.

To build a mobile view, you can create a new view in the Views/Home folder by right-clicking the folder and choosing Add ⇒ View. Name the view Index.mobile. Now you can create content in the view that is displayed only when the page is requested from a mobile browser. The Index.mobile view is presented in Listing 27-10 (files Views/Home/Index.mobile.cshtml and Views/Home/Index.mobile.vbhtml in the code download for this chapter).

LISTING 27-10: The Index mobile view

VB

@Code
    ViewData("Title") = "Index.mobile"
End Code
 
<h2>Index Mobile View</h2>
This page is being viewed in a mobile browser

C#

@{
    ViewBag.Title = "Index Mobile";
}
 
<h2>Index Mobile View</h2>
This page is being viewed in a mobile browser

Running the application and viewing it in a mobile browser displays the content from the mobile version of the Index view, whereas viewing the application in a desktop browser displays the content from the standard Index view. Figure 27-11 shows the Index view displayed in a desktop browser. Figure 27-12 shows the same view in a mobile browser. You can see that both browsers are pointed to the same URL, but the displayed content is different.

FIGURE 27-11

image

FIGURE 27-12

image

Providing Display Modes

Using mobile-specific views, you can provide specific views and layouts for use when any mobile browser makes a request. But you may need another level of customization such as providing a specific view to a particular browser or device. For example, if someone using an iPhone or an iPad views your site, you may want to provide a view that is styled more like a native application on that device.

If you have been building applications for the web for any length of time, you have probably had to write styles or script to make something work in a particular browser. If so, you know how painful it is to target multiple specific browsers or platforms in a single page. ASP.NET MVC 4 introduces a new feature called Display Modes, which makes targeting a specific browser or platform easier. And, like many new features in MVC 4, it uses a convention over configuration approach.

Creating a new display mode involves using a particular naming convention for your views and browser sniffing for particular trigger conditions. To see this in action, create a particular view that displays when an iPhone browses the site. To do so, create a new view in the Views\Home folder and name the view Index.iphone. Then create content in the view that displays only when the page is requested from an iPhone. The Index.iphone view is presented in Listing 27-11 (files Views\Home\Index.iphone.cshtml and Views\Home\Index.iphone.vbhtml in the code download for this chapter).

LISTING 27-11: The Index view for an iPhone

VB

@Code
    ViewData("Title") = "Index.iphone"
End Code
 
<h2>Index iPhone View</h2>
This page is being viewed on an iPhone

C#

@{
    ViewBag.Title = "Index iPhone";
}
 
<h2>Index iPhone View</h2>
This page is being viewed on an iPhone

Now, you need to register a display mode for the iphone suffix. You need to register the display mode only once, so you typically do this in the Global.asax in the Application_Start event handler. In the Global.asax file, include a reference to the System.Web.WebPages namespace:

VB

Imports System.Web.WebPages

C#

using System.Web.WebPages;

Now you need to register the display mode with the DisplayModeProvider. In the case of the iPhone, you want to specify that the condition for the display mode is that the user agent contains the word “iPhone.” Listing 27-12 shows the Global.asax file after adding the display mode registration. You can find the code in files Global.asax.cs and Global.asax.vb in the root of the MvcMobileCS and MvcMobileVB projects in the code download for this chapter.

LISTING 27-12: Global.asax file showing the Display Mode registration

VB

' Note: For instructions on enabling IIS6 or IIS7 classic mode, 
' visit http://go.microsoft.com/?LinkId=9394802
Imports System.Web.Http
Imports System.Web.Optimization
Imports System.Web.WebPages
 
Public Class MvcApplication
    Inherits System.Web.HttpApplication
 
    Sub Application_Start()
        AreaRegistration.RegisterAllAreas()
 
        WebApiConfig.Register(GlobalConfiguration.Configuration)
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters)
        RouteConfig.RegisterRoutes(RouteTable.Routes)
        BundleConfig.RegisterBundles(BundleTable.Bundles)
        AuthConfig.RegisterAuth()
 
        DisplayModeProvider.Instance.Modes.Insert(0, _
            New DefaultDisplayMode("iphone") 
            With {.ContextCondition = Function(context As HttpContextBase) 
            context.GetOverriddenUserAgent().IndexOf("iPhone", 
            StringComparison.OrdinalIgnoreCase) >= 0})
 
    End Sub
End Class

C#

using System;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System.Web.WebPages;
 
namespace MvcMobile
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801
 
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
 
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
 
            DisplayModeProvider.Instance.Modes.Insert(0, new
                DefaultDisplayMode("iphone")
            {
                ContextCondition = (context =>
                  context.GetOverriddenUserAgent().IndexOf
                  ("iPhone", StringComparison.OrdinalIgnoreCase) >= 0)
            });
        }
    }
}

The new display mode is inserted at the top of the Modes collection:

DisplayModeProvider.Instance.Modes.Insert

The new display mode is also given a name. In this case, it is called “iphone”:

new DefaultDisplayMode("iphone")

The name of the display mode is what you use as the suffix of the view naming convention Index.iphone. You could have used whatever name you’d liked here. Just make sure that the name of the display mode matches the suffix used in the name of the view.

Finally, you specify the condition that must be met to invoke the display mode. In this case, the word “iPhone” must exist in the user agent string:

context.GetOverriddenUserAgent()
    .IndexOf("iPhone", StringComparison.OrdinalIgnoreCase) >= 0)

NOTE Note that you use the GetOverriddenUserAgent method to get the user agent string. GetOverriddenUserAgent returns the overridden user agent value or the actual user agent string if no override has been specified. The technique of overriding the user agent string is often used to provide users with the capability to see the desktop view of a page even though they are using a mobile device.

Now when viewing the page using an iPhone, you will see the iPhone version of the page specified by the iPhone-specific view. Figure 27-13 shows the Index view as seen on an iPhone.

FIGURE 27-13

image

Including jQuery Mobile and the ViewSwitcher

Once you begin to develop views that are designed specifically for mobile browsers, you may want to include mobile-specific functionality and client libraries in those views. One of the common mobile JavaScript libraries is jQuery Mobile. jQuery Mobile is an open source library for building UIs for mobile devices based on jQuery Core. Although ASP.NET MVC 4 includes many features to aid with mobile web application development, the ASP.NET MVC project templates don’t include jQuery Mobile by default (with the exception of the Mobile Application project template).

If you want to install jQuery Mobile in your project, you can do so using NuGet. There is a NuGet package for installing jQuery Mobile in an ASP.NET MVC project. The NuGet Package Manager is installed by default in Visual Studio 2012. Open the Package Manager Console by clicking Tools ⇒ Library Package Manager ⇒ Package Manager Console from the Visual Studio menu. At the console prompt, run the command Install-Package jQuery.Mobile.MVC.

The jQuery.Mobile.MVC Nuget package adds a handful of files to the project, including the CSS and JavaScript files needed for jQuery Mobile. It also adds a mobile-specific Layout named _Layout.Mobile.cshtml or _Layout.Mobile.vbhtml depending on your choice of language. This mobile-specific Layout includes references to the added CSS and JavaScript files as bundles. To create these bundles, you need to include a line of code in the Global.asax file. A readme file is included with the Nuget package that provides the line of code. You must add the line of code to the Application_Start handler. Listing 27-13 provides the Application_Start handler after adding the necessary line of code (shown in bold). You can find the code for this listing in files Global.asax.cs and Global.asax.vb located in the root of the MvcMobileCS or MvcMobileVB projects in the code download for this chapter.

LISTING 27-13: Application_Start with necessary jQuery Mobile bundle

VB

    Sub Application_Start()
        AreaRegistration.RegisterAllAreas()
 
        WebApiConfig.Register(GlobalConfiguration.Configuration)
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters)
        RouteConfig.RegisterRoutes(RouteTable.Routes)
        BundleConfig.RegisterBundles(BundleTable.Bundles)
        AuthConfig.RegisterAuth()
 
        DisplayModeProvider.Instance.Modes.Insert(0, _
            New DefaultDisplayMode("iphone") 
            With {.ContextCondition = Function(context As HttpContextBase) 
            context.GetOverriddenUserAgent().IndexOf("iPhone", 
            StringComparison.OrdinalIgnoreCase) >= 0})
 
        BundleMobileConfig.RegisterBundles(BundleTable.Bundles)
    End Sub

C#

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
 
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
 
            DisplayModeProvider.Instance.Modes.Insert(0, new
                DefaultDisplayMode("iphone")
            {
                ContextCondition = (context =>
                  context.GetOverriddenUserAgent().IndexOf
                  ("iPhone", StringComparison.OrdinalIgnoreCase) >= 0)
            });
 
            BundleMobileConfig.RegisterBundles(BundleTable.Bundles);
        }

Besides the files that support jQuery Mobile, the Nuget package also adds a controller and partial view for a ViewSwitcher. The ViewSwitcher allows a user to switch between the mobile browser view and the standard desktop browser view. You may have seen other mobile websites that provide a way to view the desktop version of the site on a mobile device. That is what the ViewSwitcher does for you. The ViewSwitcher partial view is included in the mobile Layout file:

@Html.Partial("_ViewSwitcher")

The ViewSwitcher partial view renders a link that allows the user to switch to the desktop view of your application. If you want your users to be able to switch back to the mobile view, you can add this partial view to your standard Layout file as well. Listing 27-14 (code files Views\Shared\_ViewSwitcher.cshtml and Views\Shared\_ViewSwitcher.vbhtml) shows the ViewSwitcher partial view.

LISTING 27-14: ViewSwitcher partial view

VB

@If Request.Browser.IsMobileDevice And Request.HttpMethod = "GET" Then
    @:<div class="view-switcher ui-bar-a">
        @If ViewContext.HttpContext.GetOverriddenBrowser().IsMobileDevice Then
            @: Displaying mobile view
            @Html.ActionLink("Desktop view", "SwitchView", "ViewSwitcher", New With 
                {.mobile = False, .returnUrl = Request.Url.PathAndQuery}, New With 
                {.rel = "external"})
        Else
            @: Displaying desktop view
            @Html.ActionLink("Mobile view", "SwitchView", "ViewSwitcher", New With 
                {.mobile = True, .returnUrl = Request.Url.PathAndQuery}, New With 
                {.rel = "external"})
        End If
    @:</div>
End If

C#

@if (Request.Browser.IsMobileDevice && Request.HttpMethod == "GET")
{
    <div class="view-switcher ui-bar-a">
        @if (ViewContext.HttpContext.GetOverriddenBrowser().IsMobileDevice)
        {
            @: Displaying mobile view
            @Html.ActionLink("Desktop view", "SwitchView", "ViewSwitcher", new {
                mobile = false, returnUrl = Request.Url.PathAndQuery }, new { rel =
                "external" })
        } 
        else 
        {
            @: Displaying desktop view
            @Html.ActionLink("Mobile view", "SwitchView", "ViewSwitcher", 
                new { mobile= true, 
                returnUrl = Request.Url.PathAndQuery }, 
                new { rel = "external"
                })
        }
    </div>
}

The ViewSwitcher is visible only if the request is coming from a mobile browser:

@if (Request.Browser.IsMobileDevice && Request.HttpMethod == "GET")

If the request is coming from a mobile browser, the GetOverriddenBrowser method is called to determine if the browser type has been overridden. Based on the response, a link is displayed to switch the view between the mobile and standard views:

@if (ViewContext.HttpContext.GetOverriddenBrowser().IsMobileDevice)

The ActionLinks reference the SwitchView action of the ViewSwitcher controller that was added by the jQuery.Mobile.MVC Nuget package. Listing 27-15 (files Controllers\ViewSwitcherController.cs and Controllers\ViewSwitcherController.vb in the code download for this chapter) shows the ViewSwitcher controller.

LISTING 27-15: ViewSwitcher controller

VB

Imports System.Web.WebPages
 
Namespace MvcMobileVB
    Public Class ViewSwitcherController
        Inherits System.Web.Mvc.Controller
 
        Public Function SwitchView(mobile As Boolean, returnUrl As String) As 
            RedirectResult
            If Request.Browser.IsMobileDevice = mobile Then
                HttpContext.ClearOverriddenBrowser()
            Else
                HttpContext.SetOverriddenBrowser(DirectCast(IIf(mobile, 
                    BrowserOverride.Mobile, BrowserOverride.Desktop), 
                    BrowserOverride))
            End If
            Return Redirect(returnUrl)
        End Function
 
    End Class
End Namespace

C#

using System.Web.Mvc;
using System.Web.WebPages;
 
namespace MvcMobile.Controllers
{
    public class ViewSwitcherController : Controller
    {
        public RedirectResult SwitchView(bool mobile, string returnUrl) {
            if (Request.Browser.IsMobileDevice == mobile)
                HttpContext.ClearOverriddenBrowser();
            else
                HttpContext.SetOverriddenBrowser(mobile ? BrowserOverride.Mobile :
                    BrowserOverride.Desktop);
 
            return Redirect(returnUrl);
        }
    }
}

Figure 27-14 shows the application viewed in a mobile browser after the addition of the jQuery.Mobile.MVC Nuget package.

FIGURE 27-14

image

Using the Mobile Application Project Template

So far all the MVC 4 features presented involve supporting both desktop and mobile browsers in one way or another. What if you just want to build a purely mobile web application? What if you are not interested in having to provide a desktop browsing experience? ASP.NET MVC 4 provides a project template that is targeted directly at mobile devices —vvthe Mobile Application project template. You can see the Mobile Application project template in the New ASP.NET MVC 4 Project dialog box, shown in Figure 27-10.

When you create a project with the Mobile Application project template, you’ll notice that the overall structure of the project is the same as the other project templates. You still have the same views, controllers, and models. If you look at the content of the views, though, you’ll see that they are built specifically for mobile browsers. jQuery Mobile is included by default and is implemented in all the views. All the default page elements are designed specifically for mobile devices specifying the data- attributes used by jQuery Mobile. Figure 27-15 shows an application built using the Mobile Application project template viewed in a mobile browser.

FIGURE 27-15

image

TESTING YOUR MOBILE APPLICATIONS

It is possible to test some aspects of a mobile website by browsing it on a desktop and decreasing the size of the browser window. However, to truly test a mobile website, you need to view it on a mobile device. Unless you have one of each device you want to test on, you will need to find other ways to test your mobile site. Two of the more common ways to test without an actual device are with browsers that let you change the HTTP Header information and emulators.

Browsers, such as Mozilla Firefox and Google Chrome, have multiple extensions available that you can use to modify HTTP Header information in a request. By modifying this information in a browser request, you can trick a web server into thinking the request is coming from a mobile device.

The other way to test a mobile site is with an emulator for the particular device you are trying to test on. You can install the Windows Phone emulator by installing the Windows Phone SDK. As of this writing, the Windows Phone 8 SDK requires Hyper-V and a 64-bit version of Windows 8 Pro. If you don’t have hardware to support running the Windows Phone 8 emulator, you can still install the Windows Phone SDK 7.1. Although it is not the latest version of the emulator, it still enables you to test your site on IE9 running on Windows Phone 7 or 7.5.

Two other popular devices used for testing mobile websites are Apple’s iPhone and iPad devices. Electric Plum offers an iPhone and iPad simulator as part of its Electric Mobile Studio. It has partnered with Microsoft to provide the iPhone and iPad simulators as extensions to version 2 of WebMatrix, a free lightweight web development tool developed by Microsoft. The simulators are also available as a Visual Studio 2012 extension. By installing the Electric Mobile Studio extension in Visual Studio 2012, the iPad and iPhone simulators become available in the “Browse With. . .” option of Visual Studio. Figure 27-16 shows the “Browse With. . .” drop-down, which displays after you install the Electric Mobile Studio extension.

FIGURE 27-16

image

SUMMARY

Developers have been building mobile websites since the late 1990s. But as the popularity and use of mobile devices continues to increase, the demand for sites that are compatible with mobile devices is also increasing.

Despite the amount of time developers have been building mobile websites, the challenges remain the same. Building a mobile website requires different design decisions and considerations. Plenty of options are available, ranging from adaptive design of a single website to parallel websites or pages targeted directly at mobile devices.

Tools like Visual Studio 2012 and features like those available in the latest version of ASP.NET MVC make the task of developing mobile sites much easier. Testing these mobile sites has also become easier through the use of browser extensions, emulators, and simulators.

You no longer have any excuse to avoid building sites designed to be viewed on both a desktop and a mobile device.