Mobile enabled web apps with ASP.NET MVC 3 and jQuery Mobile

In my previous blog posts, I have demonstrated a simple web app using ASP.NET MVC 3 and EF Code First. In this post, I will be focus on making this application for mobile devices. A single web site will be used for both mobile browsers and desktop browsers. If users are accessing the web app from mobile browsers, users will be redirect to mobile specific pages and will get normal pages if users are accessing from desktop browsers. In this demo app, the mobile specific pages are maintained in an ASP.NET MVC Area named Mobile and mobile users will be redirect to MVC Area Mobile.

Let’s add a new area named Mobile to the ASP.NET MVC app. For adding Area, right click the ASP.NET MVC project and  select Area from Add option. Our mobile specific pages using jQuery Mobile will be maintained in the Mobile Area.

ASP.NET MVC Global filter for redirecting mobile visitors to Mobile area

Let’s add an ASP.NET MVC Global filter for redirecting mobile visitors to Mobile area. The below Global filter is taken from the sample app http://aspnetmobilesamples.codeplex.com/ created by the ASP.NET team. The below filer will redirect the Mobile visitors to an ASP.NET MVC Area Mobile.


  1. public class RedirectMobileDevicesToMobileAreaAttribute : AuthorizeAttribute
  2.     {
  3.         protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
  4.         {
  5.             // Only redirect on the first request in a session
  6.             if (!httpContext.Session.IsNewSession)
  7.                 return true;
  8.  
  9.             // Don't redirect non-mobile browsers
  10.             if (!httpContext.Request.Browser.IsMobileDevice)
  11.                 return true;
  12.  
  13.             // Don't redirect requests for the Mobile area
  14.             if (Regex.IsMatch(httpContext.Request.Url.PathAndQuery, "/Mobile($|/)"))
  15.                 return true;
  16.  
  17.             return false;
  18.         }
  19.  
  20.         protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
  21.         {
  22.             var redirectionRouteValues = GetRedirectionRouteValues(filterContext.RequestContext);
  23.             filterContext.Result = new RedirectToRouteResult(redirectionRouteValues);
  24.         }
  25.  
  26.         // Override this method if you want to customize the controller/action/parameters to which
  27.         // mobile users would be redirected. This lets you redirect users to the mobile equivalent
  28.         // of whatever resource they originally requested.
  29.         protected virtual RouteValueDictionary GetRedirectionRouteValues(RequestContext requestContext)
  30.         {
  31.             return new RouteValueDictionary(new { area = "Mobile", controller = "Home", action = "Index" });
  32.         }
  33.     }


Let’s add the global filer RedirectMobileDevicesToMobileAreaAttribute to the global filter collection in the Application_Start() of Global.asax.cs file

 

  1. GlobalFilters.Filters.Add(new RedirectMobileDevicesToMobileAreaAttribute(), 1);


Now your mobile visitors will be redirect to the Mobile area. But the browser detection logic in the RedirectMobileDevicesToMobileAreaAttribute filter will not be working in some modern browsers and some conditions. But the good news is that ASP.NET’s browser detection feature is extensible and will be greatly working with the open source framework 51Degrees.mobi. 51Degrees.mobi is a Browser Capabilities Provider that will be working with ASP.NET’s Request.Browser and will provide more accurate and detailed information. For more details visit the documentation page at http://51degrees.codeplex.com/documentation.

Let’s add a reference to 51Degrees.mobi library using NuGet

Nuget_51Mobi

We can easily add the 51Degrees.mobi from NuGet and this will update the web.config for necessary configuartions.

Mobile Web App using jQuery Mobile Framework

jQuery Mobile Framework is built on top of jQuery that provides top-of-the-line JavaScript in a unified User Interface that works across the most-used smartphone web browsers and tablet form factors. It provides an easy way to develop user interfaces for mobile web apps. The current version of the framework is jQuery Mobile Alpha 3.
We need to include the following files to use jQuery Mobile.
  • The jQuery Mobile CSS file (jquery.mobile-1.0a3.min.css)
  • The jQuery library (jquery-1.5.min.js)
  • The jQuery Mobile library (jquery.mobile-1.0a3.min.js)

Let’s add the required jQuery files directly from jQuery CDN . You can download the files and host them on your own server.

jQuery Mobile page structure

The basic jQuery Mobile page structure is given below

<!DOCTYPE html>
<html>
  <head>
  <title>Page Title</title>
  <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a1.min.css" />
  <script src="http://code.jquery.com/jquery-1.5.min.js"></script>
  <script src="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.js"></script>
</head>
<body>

<div data-role="page">

  <div data-role="header">
    <h1>Page Title</h1>
  </div>

  <div data-role="content">
    <p>Page content goes here.</p>   
  </div>

  <div data-role="footer">
    <h4>Page Footer</h4>
  </div>
</div>

</body>
</html>

The data- attributes are the new feature of HTML5 so that jQuery Mobile will be working on browsers that supporting HTML 5. You can get a detailed browser support details from http://jquerymobile.com/gbs/ . In the Head section we have included the Core jQuery javascript file and jQuery Mobile Library and the core CSS Library for the UI Element Styling. These jQuery files are minified versions and will improve the performance of page load on Mobile Devices.

The jQuery Mobile pages are identified with an element with the data-role="page" attribute inside the <body> tag.


<div data-role="page">
</div>


Within the "page" container, any valid HTML markup can be used, but for typical pages in jQuery Mobile, the immediate children of a "page" are div element with data-roles of "header", "content", and "footer".

<div data-role="page">
    <div data-role="header">...</div>
    <div data-role="content">...</div>
    <div data-role="footer">...</div>
</div>


The div data-role="content" holds the main content of the HTML page and will be used for making user interaction elements. The div data-role="header" is header part of the page and div data-role="footer" is the footer part of the page.

Creating Mobile specific pages in the Mobile Area


Let’s create Layout page for our Mobile area

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <title>@ViewBag.Title</title>
  5.     <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.css" />
  6.     <script src="http://code.jquery.com/jquery-1.5.min.js"></script>
  7.     <script src="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.js"></script>    
  8. </head>
  9.  
  10.    <body>
  11. @RenderBody()   
  12. </body>
  13. </html>


In the Layout page, I have given reference to jQuery Mobile JavaScript files and the CSS file.


Let’s add an Index view page

Index.chtml

  1. @{
  2.     ViewBag.Title = "Index";
  3. }
  4. <div data-role="page">
  5. <div data-role="header">
  6.      <h1>Expense Tracker Mobile</h1>
  7. </div>
  8. <div data-role="content">  
  9. <ul data-role="listview">
  10.     <li>@Html.Partial("_LogOnPartial")</li>
  11.      <li>@Html.ActionLink("Home", "Index", "Home")</li>
  12.      <li>@Html.ActionLink("Category", "Index", "Category")</li>                    
  13.      <li>@Html.ActionLink("Expense", "Index", "Expense")</li>
  14. </ul>
  15. </div>
  16. <div data-role="footer">      
  17.     Shiju Varghese | <a href="http://weblogs.asp.net/shijuvarghese">Blog
  18.     </a> | <a href="http://twitter.com/shijucv">Twitter</a>
  19.   </div>
  20. </div>

 

In the Index page, we have used data-role “listview” for showing our content as List View

Let’s create a data entry screen

create.cshtml

  1. @model MyFinance.Domain.Category
  2. @{
  3.     ViewBag.Title = "Create Category";
  4. }
  5.   <div data-role="page">
  6. <div data-role="header">
  7.      <h1>Create Category</h1>    
  8.         @Html.ActionLink("Home", "Index","Home",null, new { @class = "ui-btn-right" })   
  9.   </div>    
  10.   <div data-role="content">
  11.     @using (Html.BeginForm("Create","Category",FormMethod.Post))
  12.     {
  13.       <div data-role="fieldcontain">
  14.        @Html.LabelFor(model => model.Name)
  15.        @Html.EditorFor(model => model.Name)
  16.        <div>
  17.           @Html.ValidationMessageFor(m => m.Name)
  18.        </div>
  19.         </div>
  20.         <div data-role="fieldcontain">
  21.         @Html.LabelFor(model => model.Description)
  22.         @Html.EditorFor(model => model.Description)          
  23.         </div>           
  24.         <div class="ui-body ui-body-b">
  25.         <button type="submit" data-role="button" data-theme="b">Save</button>
  26.       </div>
  27.     }       
  28. </div>
  29. </div>

 

In jQuery Mobile, the form elements should be placed inside the data-role="fieldcontain"

The below screen shots show the pages rendered in mobile browser

Index Page

Index

Create Page

create_category

Source Code


You can download the source code from http://efmvc.codeplex.com  

Summary

We have created a single  web app for desktop browsers and mobile browsers. If a user access the site from desktop browsers, users will get normal web pages and get mobile specific pages if users access from mobile browsers. If users are accessing the website from mobile devices, we will redirect to a ASP.NET MVC area Mobile. For redirecting to the Mobile area, we have used a Global filer for the redirection logic and used open source framework 51Degrees.mobi for the better support for mobile browser detection. In the Mobile area, we have created the pages using jQuery Mobile and users will get mobile friendly web pages. We can create great mobile web apps using ASP.NET MVC  and jQuery Mobile Framework.

15 Comments

  • Great work, this will be an inspiration for me to try on go4cinema

  • How can we install this in mobile. will it be installable in iPhone.

  • @Rupesh Kumar Tiwari,
    This is a web app and will be deployed in a web server.

  • Thanks pal for sharing the post, the sample code has helped me in getting out of this trouble, Its very kind of you.
    Thank again :)

  • Thanks for your great post. It really helped me make my web site mobile-enabled. One thing curious though is why we need to copy the same controller classes into the mobile area? I thought MVC is for sharing controllers for different views. I hope there is another way because it's obviously redundant code.

  • Hey thank you so much for this great article!

    I have one question.
    How do I go about to have a link to my root website (the desctop version) for my mobile users if i want them to be able to chose if they want to view the website with 51degree or as normal users view it?

    Thanks in advance

  • I have a Custom MVCRouteHandler to managed the culture, my routes in the global.asax are like this:

    routes.Add("Default",
    new Route(" {langID}/{controller}/{action}",
    new CultureRouteHandler())
    {
    Defaults = new RouteValueDictionary(
    new {controller = "Home", action = "Index"}),

    });
    How can i do to avoid the error multiples controller, i can't set the namespace property like in the map.route...

  • Hi Shiju, thanks for this post. Can you tell me how i can access the application in mobile. I can see , in the Image you have pasted, the url mentioned as localhost. But i was unable to access the application in mobile as well as in mobile emulator .

  • Hi Shiju,

    Your blog is really good and helpful. We are looking for ajaxenabled jquerymobile using MVC3 Sample application which load dynamic data from database to .cshtml page. We try at our end by making $.mobile.ajaxEnable = true in mobileinit event but its not working properly on $.mobile.changePage event and making multiple time call to javascript placed inside body tag of .cshtml page

  • Wonderful post - I was looking for a similar article. Thanks for sharing this article to your reader. You give very nice information about this article

  • Great! Just a question. I want to use exactly the same infrastructure, models and controllers as in original app but on mobile, render different views and css. What would be the easiest way to do it? I don't want to check every controller action and open different view based on the result of browser check. Is there a way to redirect users to Area views but still use the same controllers? ( I hope I am not confusing you)

  • If you want to reuse controllers, then you can specify to search the root namespace in your area registration:


    context.MapRoute(
    "m_default",
    "m/{controller}/{action}/{id}",
    new {controller = "Home", action = "Index", id = UrlParameter.Optional},
    new[] {"Example.m.Controllers", "Example.Controllers"}
    );

  • Hi it's me, I am also visiting this website daily, this web page is in fact good and the people are really sharing fastidious thoughts.

  • I've been exploring for a little bit for any high quality articles or weblog posts on this kind of house .
    Exploring in Yahoo I ultimately stumbled upon this web site.
    Studying this info So i am happy to express that I've a
    very just right uncanny feeling I found out exactly what I
    needed. I most surely will make certain to do not put out of your mind this web site and give it a glance on a constant basis.

  • I think the admin of this website is truly working hard
    in support of his website, because here every material is quality based
    material.

Comments have been disabled for this content.