Click here to Skip to main content
Click here to Skip to main content

Detecting a mobile browser in ASP.NET

, 24 Mar 2009
Rate this:
Please Sign up or sign in to vote.
How to detect a mobile device accessing your ASP.NET website.

Introduction

A simple function to detect if a user vesting your site is on a mobile device or not.

Background

This is my first CodeProject article. The articles on this site have helped me out so much in learning .NET. I just hope this can help someone out as well.

I needed the ability to detect if a user was browsing from a mobile device or a normal web browser and redirect to the appropriate version of my site. I found very little ASP.NET tutorials that worked. So I decided to take a few different methods and language options I found on the net and put them into one simple ASP.NET method.

Using the Code

It is just a static boolean method that gets called, isMobileBrowser():

public static bool isMobileBrowser()
{
    //GETS THE CURRENT USER CONTEXT
    HttpContext context = HttpContext.Current;

    //FIRST TRY BUILT IN ASP.NT CHECK
    if (context.Request.Browser.IsMobileDevice)
    {
        return true;
    }
    //THEN TRY CHECKING FOR THE HTTP_X_WAP_PROFILE HEADER
    if (context.Request.ServerVariables["HTTP_X_WAP_PROFILE"] != null)
    {
        return true;
    }
    //THEN TRY CHECKING THAT HTTP_ACCEPT EXISTS AND CONTAINS WAP
    if (context.Request.ServerVariables["HTTP_ACCEPT"] != null && 
        context.Request.ServerVariables["HTTP_ACCEPT"].ToLower().Contains("wap"))
    {
        return true;
    }
    //AND FINALLY CHECK THE HTTP_USER_AGENT 
    //HEADER VARIABLE FOR ANY ONE OF THE FOLLOWING
    if (context.Request.ServerVariables["HTTP_USER_AGENT"] != null)
    {
        //Create a list of all mobile types
        string[] mobiles =
            new[]
                {
                    "midp", "j2me", "avant", "docomo", 
                    "novarra", "palmos", "palmsource", 
                    "240x320", "opwv", "chtml",
                    "pda", "windows ce", "mmp/", 
                    "blackberry", "mib/", "symbian", 
                    "wireless", "nokia", "hand", "mobi",
                    "phone", "cdm", "up.b", "audio", 
                    "SIE-", "SEC-", "samsung", "HTC", 
                    "mot-", "mitsu", "sagem", "sony"
                    , "alcatel", "lg", "eric", "vx", 
                    "NEC", "philips", "mmm", "xx", 
                    "panasonic", "sharp", "wap", "sch",
                    "rover", "pocket", "benq", "java", 
                    "pt", "pg", "vox", "amoi", 
                    "bird", "compal", "kg", "voda",
                    "sany", "kdd", "dbt", "sendo", 
                    "sgh", "gradi", "jb", "dddi", 
                    "moto", "iphone"
                };

        //Loop through each item in the list created above 
        //and check if the header contains that text
        foreach (string s in mobiles)
        {
            if (context.Request.ServerVariables["HTTP_USER_AGENT"].
                                                ToLower().Contains(s.ToLower()))
            {
                return true;
            }
        }
    }

    return false;
}

Points of Interest

As you can see, the above code is written in new syntax. But, it can easily be changed to work on any version of .NET. Instead of using the short hand array initializer, use new string[] {} (instead of new[] {}).

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Vincent Van Zyl
Team Leader Blueworld Communities
South Africa South Africa
I am fairly new to programming as I began programming in asp.net and C# in 2005.
 
But I have learned a lot in a very short space of time thanks to code project and sitepoint. I work in a very fast past company which also helped speed things up

Comments and Discussions

 
Questiondon't repeat the request.servervariables request PinmemberMark Findlay9-Jun-14 6:04 
QuestionThe way to build mobiles array is inportant PinmemberMember 773936631-Jan-13 8:27 
GeneralMy vote of 1 Pinmemberfawad13-Mar-12 22:56 
SuggestionNew devices PinmemberBoci5-Dec-11 9:53 
GeneralRe: New devices Pinmemberblagoja29-Dec-11 0:50 
Questionthanks Pinmemberhugorafael20-Jun-11 9:58 
GeneralThanks PinmemberNikhil_Patel12327-Apr-11 4:01 
GeneralImproved version PinmemberHarvo23-Nov-10 15:08 
Hi,
 
I cleaned up the code a bit, improved its performance, added it as an extension method, and spruced
up the user-agent detection logic based on content found from http://www.detectmobilebrowser.com. The full
code is shown below.
 
By the way, the optimization that was mentioned previously to treat as non-mobile if the browser
is not "Unknown" is not correct, that should be removed. (From my iPhone, for example,
Request.Browser.IsMobileDevice returns false, and Request.Browser.Browser is something like "AppleMac-XXX".)
 
Cheers,
 
Harvo
 
    public static class HttpRequestBaseExtensions
    {
        #region Private Fields
 
        // These regular expressions retrieved from http://detectmobilebrowser.com/ "Open source mobile phone detection".
        private static Regex MobileBrowsers = new Regex(@"android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|symbian|treo|up\\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino", RegexOptions.IgnoreCase | RegexOptions.Multiline);
        private static Regex MobileApps = new Regex(@"1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|e\\-|e\\/|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\\-|2|g)|yas\\-|your|zeto|zte\\-", RegexOptions.IgnoreCase | RegexOptions.Multiline);
 
        #endregion
 
        public const string ViewMobileSiteCookieName = "ViewMobile";
 
        /// <summary>
        /// Determines if the request emanated from a mobile-device client; and stores the result in a cookie on the response.
        /// </summary>
        /// <param name="request"></param>
        /// <param name="Response"></param>
        /// <returns></returns>
        public static bool IsMobileClient(this HttpRequestBase request, HttpResponseBase Response)
        {
            bool isMobile = false;
            bool isCookieSet = false;
            var viewMobileCookie = request.Cookies[ViewMobileSiteCookieName];
 
            if (viewMobileCookie != null && bool.TryParse(viewMobileCookie.Value, out isMobile))
            {
                isCookieSet = true;
            }
            else if (request.Browser.IsMobileDevice)
            {
                isMobile = true;
            }
            else if (request.ServerVariables["HTTP_X_WAP_PROFILE"].IsNotEmpty())
            {
                isMobile = true;
            }
            else if
                (
                    request.ServerVariables["HTTP_ACCEPT"].IsNotEmpty()
                    &&
                    (
                        request.ServerVariables["HTTP_ACCEPT"].ToLower().Contains("wap")
                        || request.ServerVariables["HTTP_ACCEPT"].ToLower().Contains("wml+xml")
                    )
                )
            {
                isMobile = true;
            }
            else if (request.ServerVariables["HTTP_USER_AGENT"].IsNotEmpty())
            {
                string userAgent = request.ServerVariables["HTTP_USER_AGENT"];
                isMobile = ((MobileBrowsers.IsMatch(userAgent) || MobileApps.IsMatch(userAgent.Substring(0, 4))));
            }
 
            // Store the result as a cookie.
            if(!isCookieSet)
                Response.Cookies.Add(new HttpCookie(ViewMobileSiteCookieName, isMobile.ToString()));
 
            return isMobile;
        }
    }

GeneralRe: Improved version PinmemberDaniel Gidman5-May-11 9:04 
GeneralRe: Improved version PinmemberHarvo5-May-11 10:02 
GeneralRe: Improved version Pinmembersanilpnair8-Aug-11 4:03 
GeneralRe: Improved version PinmemberLe Cong Thanh16-Sep-11 6:19 
GeneralGreat article PinmemberORamses5-Sep-10 0:42 
Generalsome little enhancements Pinmembersmartcatxxx11-Oct-09 7:02 
GeneralDetect Mobile Infomation PinmemberAmimpat31-Jul-09 1:12 
GeneralRe: Detect Mobile Infomation [modified] PinmemberDutchMafia13-Aug-09 3:44 
GeneralRe: Detect Mobile Infomation PinmemberAmaresh Jois5-Aug-10 18:46 
GeneralRe: Detect Mobile Infomation PinmemberAmaresh Jois27-Aug-10 2:40 
GeneralRe: Detect Mobile Infomation PinmemberJMatthewson14-Sep-12 3:00 
GeneralThis code contains false positives! PinmemberEricLaw14-Jul-09 8:28 
GeneralRe: This code contains false positives! PinmemberWendy Youngblood30-Mar-10 6:58 
GeneralBug Pinmemberthezone1237-Apr-09 22:44 
GeneralRe: Bug Pinmembermgbaldwin13-Jul-09 1:42 
Generalthanks, Pinmemberjusjusjus30-Mar-09 22:26 
GeneralThanks Pinmemberthund3rstruck24-Mar-09 7:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140814.1 | Last Updated 24 Mar 2009
Article Copyright 2009 by Vincent Van Zyl
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid