Search code examples
asp.netmobileweb-configmaster-pagesasp.net-4.5

Mobile master page not automatically triggered


With my website I used to work with the two master pages created by default in any new webforms solution (i.e Site.Master & Site.Mobile.Master). I have noticed on firefox for mobile that my mobile master page never get loaded but rather the "normal" master page. With chrome for mobile or other browser everything works fine. I made substantive changes to my solution and now the mobile master page never get loaded by default in any cases (chrome developer tools included). I have done some researches which led me to this solution that works fine with chrome but still returns false with firefox:

    protected void Page_PreInit(object sender, EventArgs e)
    {
        if (Request.Browser.IsMobileDevice)
        {
            MasterPageFile = "~/Site.Mobile.Master";
        }
    }

The problem here is that I have to include it in every single aspx page. I have done a lot of researches and must admit that the documentation about it is quite poor. Is not there some settings I can add to the web.config file or some code to add to my global.asax so that I don't have to check the browser in every aspx pages?


Solution

  • Request.Browser.IsMobileDevice is not reliable. The following helper method could detect a little bit more.

    If you want reliable detection for every device including new ones, you want to use commercial service such as 51Degrees.

    protected void Page_PreInit(object sender, EventArgs e)
    {
        // *** For debugging, I inverted if statement. 
       //      You can reverse it back after debugging. ****
        if (!IsMobileBrowser(HttpContext.Current))
            MasterPageFile = "~/Site.Desktop.Master";
        else
            MasterPageFile = "~/Site.Mobile.Master";    
    }
    
    public static bool IsMobileBrowser(HttpContext context)
    {
        // first try built in asp.net 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;
        }
    
        // Finally check the http_user_agent header variable for any one of the following
        if (context.Request.ServerVariables["HTTP_USER_AGENT"] != null)
        {
            // List of all mobile types
            string[] mobiles =
                new[]
                {
                    "android", "opera mini", "midp", "j2me", "avant", "docomo", "novarra", "palmos", "palmsource",
                    "240×320", "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", "dddi", "moto", "iphone"
                };
    
            // Check if the header contains that text
            var userAgent = context.Request.ServerVariables["HTTP_USER_AGENT"].ToLower();
    
            return mobiles.Any(userAgent.Contains);
        }
    
        return false;
    }