We recently needed to develop a mobile version for one of our Umbraco websites: www.easy972.gr. (Umbraco version 7.2.8)
Initially, we rejected the approach of using Umbraco's alternative templates for the same document type, because it was required to preserve common URLs as well as a common content tree for both the desktop and the mobile version.
We based our implementation on the following ASP.NET MVC 4 Mobile feature:
"A significant new feature in ASP.NET MVC 4 is a simple mechanism that lets you override any view (including layouts and partial views) for mobile browsers in general, for an individual mobile browser, or for any specific browser. To provide a mobile-specific view, you can copy a view file and add .Mobile to the file name. For example, to create a mobile Index view, copy Views\Home\Index.cshtml to Views\Home\Index.Mobile.cshtml."
Source: http://www.asp.net/mvc/overview/older-versions/aspnet-mvc-4-mobile-features
Therefore, in order to implement the mobile version of the website, we created a copy of every required view/partial view with filename: ‘[original-view-name].Mobile.cshtml’, and used the mobile html markup in those.
Having done that, we observed that when the client device was a desktop browser, the desktop version of the website was being loaded. Also when the client device was a mobile phone or tablet or the mobile browser emulator, then the mobile version of the website was displayed.
The problem was that the mobile version of the website shouldn't be displayed in tablet devices. Our client's requirement was to display the desktop version for tablets.
Solution 1
A possible solution was to create another copy of every mobile view with filename ‘[original-view-name].Tablet.cshtml’.
This is a fully functional solution, but with a significant drawback as far as website maintenance is concerned, because e.g. for the Homepage, we could end up with 3 files to maintain:
- Homepage.cshtml
- Homepage.Mobile.cshtml
- Homepage.Tablet.cshtml
The ‘Homepage.cshtml’ would be identical to 'Homepage.Tablet.cshtml’ (code duplication), which would make it very easy to forget applying a modification made at the desktop site, to the tablet view as well.
Solution 2
Another solution was to try and interfere with MVC 4 out of the box device detection, in order to display the desktop version to tablet clients.
This was achieved by making use of MVC 4 Display Modes, and you can refer to paragraph ‘Browser-Specific Views’ at: http://www.asp.net/mvc/overview/older-versions/aspnet-mvc-4-mobile-features. Another useful link on Display Modes: https://msdn.microsoft.com/en-us/magazine/dn296507.aspx
Here is the final C# Code that solved the problem:
DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("") { ContextCondition = (context => this.DetectTablet(context.GetOverriddenUserAgent()) && !this.DetectMobile(context.GetOverriddenUserAgent()) ) }); DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("Mobile") { ContextCondition = (context => this.DetectMobile(context.GetOverriddenUserAgent()) && !this.DetectTablet(context.GetOverriddenUserAgent()) ) });
The functions DetectMobile και DetectTablet are custom device detection functions:
protected bool DetectTablet(string userAgent) { var tablets = new[] { "ipad", "android 3", "xoom", "sch-i800", "tablet", "kindle", "playbook" }; return ( tablets.Any(userAgent.ToLower().Contains) || (userAgent.ToLower().Contains("android") && !userAgent.ToLower().Contains("mobile"))); } protected bool DetectMobile(string userAgent) { var 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", "Opera Mini" }; return (mobiles.Any(userAgent.Contains)); }