Displaying mobile friendly page without changing the URL in ASP.NET with C# (NO CSS)

Sheonarayan
Posted by in ASP.NET category on for Advance level | Points: 250 | Views : 24219 red flag
Rating: 5 out of 5  
 3 vote(s)

Increasing use of handheld devices such as Mobile, iPad, Tablet has made mobile friendly website a mandatory for any website or web applications. In this article, we will learn how to develop mobile friendly website easily without using jQuery or even screen specific CSS. All you need to know is ASP.NET with C# and all of it is done without changing the URL of the page.


 Download source code for Displaying mobile friendly page without changing the URL in ASP.NET with C# (NO CSS)

In general following approaches are followed to develop a mobile friendly website 

  1. Create a separate website and redirect the user to mobile friendly website if user is coming from mobile devices
    - The problem with this approach is that user is redirected to different url that may create confusion to the user. Also the same content in two different url may confuse the SEO robots.

  2. Create a page with CSS3 @media screen element that detects the screen width of the device and apply the CSS written for mobile devices (to decrease the width of the page or shifting right/left content to the bottom of the page). 
    - The problem with this approach is that it loads the original bulky pages that was originally designed for Desktop but because user is coming from Mobile device so HTML elements are manipulated to fit into the screen.

  3. Using jQuery that detects the mobile device request and manipulate the element that will fit the page in the screen.
    - This has again almost same problem that has been explained in point number 2.
All above three approaches has their own drawbacks and I personally do not feel comfortable using any of them being a pure server side programmer. 
  

Objective

In this article, we will learn following
  1. Detecting mobile request using a plugin (simple, easy, reliable and free)
  2. Sending mobile request to a mobile page developed for mobile screen (internally, without changing the URL)
  3. Sending response to the users browser that is purely for mobile with no extra content
In all above process the URL doesn't change, so the user experience is surprisingly awesome.

Using the code


As written above, we are going to use a plugin that detects mobile request, so go ahead and visit this link http://51degrees.mobi/ and download the plugin (Once the download is complete, Add reference of FiftyOne.Foundation.dll into your project). Alternatively, use Manage NuGet Packages ... by right clicking the Project that automatically does all the back end work for you.



To demonstrate this example, I have created a sample project and my project solution looks like below. Where we have reference of the FiftyOne.Foundation.dll and six .aspx pages, 3 each for Desktop and Mobile.



The .aspx page name ends with "M" is for mobile. For example Page1.aspx is for Desktop and Page1M.aspx is for Mobile devices.

For all .aspx pages that is for desktop, we need to do a minor change in their code behind and that change is to inherit ParentPage class from App_Code folder as shown below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : ParentPage
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
}

Now lets see ParentPage.cs code.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using FiftyOne.Foundation.Mobile.Detection;

/// <summary>
/// Summary description for ParentPage
/// </summary>
public class ParentPage : System.Web.UI.Page
{
    public ParentPage()
    {
        string screen = string.Empty;

        bool isMobile = this.Context.Request.Browser["IsMobile"] == "True";

        if (isMobile) // if coming from Mobile device
        {
            screen = "handheld";
            SetScreenSpecificPageSettings(screen);
        }
        else // if user has selected to view mobile version from Desktop
        {
            if (this.Context.Request.Cookies["screen"] != null || !string.IsNullOrWhiteSpace(this.Context.Request.QueryString["screen"]))
            {
                if (!string.IsNullOrWhiteSpace(this.Context.Request.QueryString["screen"]))
                {
                    screen = this.Context.Request.QueryString["screen"];
                    // create the cookies for subsequent request
                    this.Context.Response.Cookies["screen"].Value = this.Context.Request.QueryString["screen"];
                }
                else if (this.Context.Request.Cookies["screen"] != null)
                {
                    screen = this.Context.Request.Cookies["screen"].Value;
                }
                SetScreenSpecificPageSettings(screen);
            }
        }
    }

    private void SetScreenSpecificPageSettings(string screen)
    {
        if (screen.Equals("handheld", StringComparison.CurrentCultureIgnoreCase)) // if coming to Mobile screen, redirect to mobile page
        {
            // frame the mobile page name for this page
            var pathWithFile = string.Empty;
            if (Page.RouteData.RouteHandler == null)
            {
                pathWithFile = this.Context.Request.Url.AbsolutePath;
            }
            else
            {
                pathWithFile = ((System.Web.Routing.PageRouteHandler)Page.RouteData.RouteHandler).VirtualPath;
            }
            var extensionLength = Path.GetExtension(pathWithFile).Length;
            var mobilePage = pathWithFile.Substring(0, (pathWithFile.Length - extensionLength)) + "M" + Path.GetExtension(pathWithFile);

            var physicalFile = Server.MapPath(mobilePage);

            if (File.Exists(physicalFile)) // transfer only when the file exists for the Handheld device
            {
                this.Context.Server.Transfer(mobilePage + this.Context.Request.Url.Query, true);
            }
        }
    }
}

In the above code snippet, we have added two extra namespaces and they are following
  1. System.IO - to get the file extension
  2. FiftyOne.Foundation.Mobile.Detection - to detect whether request is coming from mobile device 
In the constructor of the ParentPage first we are checking for this.Context.Request.Browser["IsMobile"] that works only when FiftyOne namespace is added and corresponding .dll is referenced into the project.

If the request is from mobile, we are setting the screen variable  value to "handheld" and passing it to another function named "SetScreenSpecificPageSettings" else we are checking for the screen Cookies or querystring. If anyone of them are there then going to another condition.

If querystring is there then we are retrieving the value of querystring and setting to the screen variable and setting screen cookies value else if screen cookie exists then retrieving the value of cookie and setting to the screen variable.

We are setting the cookies to remember the user preference, in case user is on desktop and want to visit mobile version of the page. If you do not want this functionality, just remote this codes.

SetScreenSpecificPageSettings method

This method checks whether screen value is "handheld", if yes then sets the pathWithFile variable to the current url of the page. Gets the extension name of the page and then creates a string with mobile page name for the  requested page ("the page name ends with M") and then checks if that page exists. If it does then sends this mobile page as response to the client using Server.Transfer method.

How it works


In case user has browsed http://localhost:54082/Page1.aspx page from Desktop

Page1.aspx page is requested, as this page is inheriting
ParentPage class so its constructor is called. As the request is coming from Desktop so isMobile is false and it checks whether user wants to visit the current page in mobile version (coming with screen=handheld querystring now or earlier he/she has opted for this choice that would have set cookies), if yes then sends mobile page (Page1M.aspx) content to the browser. If not, just renders the current page that is Page1.aspx.

In case user has browsed http://localhost:54082/Page1.aspx page from Mobile

In the ParentPage class constructor isMobile will be true and request will be sent to SetScreenSpecificPageSettings method that will send mobile page content (Page1M.aspx) to the browser.

Now here is my sample website project, when browsed from Desktop (Notice the URL in the address bar).



When browsed from Handheld (mobile) devices, notice the URL in the address bar.



Other advantages when we follow this approach

  1. We can have separate MasterPages for Desktop and Mobile for total control, easy implementation and maintenance.

  2. We can have separate style sheets for Desktop and Mobile to make them lightweight and load only those .css that is required for either Desktop or Mobile.

  3. As Desktop and Mobile pages are two separate physical pages so we have complete control and total freedom to render the data in the way we want and write only code that is applicable for respective version of the page that ultimately makes it easy to load and perform better.

  4. The URL doesn't change, not even querystring is needed to denote that whether to render a page for Desktop or Mobile. The link at the footer of the page is just to given an option to the user in case he/she wants to browser mobile version of the page on Desktop explicitly.

Conclusion

Developing a mobile friendly page in ASP.NET with C# was not that easy. Thanks to 51Degree.mobi for providing reliable, lightweight plugin that  makes our life easier.

Hope this article will be useful, thanks for reading and do let us know your comments.

Reference


Page copy protected against web site content infringement by Copyscape

About the Author

Sheonarayan
Full Name: Sheo Narayan
Member Level: HonoraryPlatinum
Member Status: Administrator
Member Since: 7/8/2008 6:32:14 PM
Country: India
Regards, Sheo Narayan http://www.dotnetfunda.com
http://www.snarayan.com
Ex-Microsoft MVP, Author, Writer, Mentor & architecting applications since year 2001. Connect me on http://www.facebook.com/sheo.narayan | https://twitter.com/sheonarayan | http://www.linkedin.com/in/sheonarayan

Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)