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.
In general following approaches are followed to develop a mobile friendly website
- 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.
- 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.
- 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- Detecting mobile request using a plugin (simple, easy, reliable and free)
- Sending mobile request to a mobile page developed for mobile screen (internally, without changing the URL)
- 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
- System.IO - to get the file extension
- 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
- We can have separate MasterPages for Desktop and Mobile for total control, easy implementation and maintenance.
- 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.
- 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.
- 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