ASP.NET MVC 4 introduces Display Modes allows you to implement device or browser-specific views means you can target specific devices and provide device friendly interface. In this post, you will see how to implement mobile, tablet and TV specific views.
Lets first understand how to define display mode in the Application_Start method of the Global.asax, like so:
DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("iPhone") { ContextCondition = (context => context.GetOverriddenUserAgent().IndexOf ("iPhone", StringComparison.OrdinalIgnoreCase) >= 0) });
Here we defined iPhone in DefaultDisplayMode argument which defines the suffix of the view and defined condition if user agent has iPhone. When an iPhone browser is making the request(It has iPhone in user agent string), ASP.NET MVC look first for views matching the suffix “iPhone” and renders [view].iPhone.cshtml.
You might want to create different views of your app for desktop, TV(for GoogleTV, Internet.TV…etc), tablets(for ipad, kindle..etc) and mobiles. To implement this, I’ve added four views to home folder:
Read also: Responsive Design: Make Your Website Mobile, Tablet, Desktop Compatible
Tablet and TV Views:
Our objective is to create a common view for all tablets. So, we need to detect whether the device is tablet. You would use Request.Browser[“IsTablet”] == “True” with 51degrees.mobi premium data. This property is NOT included in the free Lite data set.
So, I converted Categorizr(A device detection script) into C#.
public string GetDeviceType(string ua) { string ret = ""; // Check if user agent is a smart TV - http://goo.gl/FocDk if (Regex.IsMatch(ua, @"GoogleTV|SmartTV|Internet.TV|NetCast|NETTV|AppleTV|boxee|Kylo|Roku|DLNADOC|CE\-HTML", RegexOptions.IgnoreCase)) { ret = "tv"; } // Check if user agent is a TV Based Gaming Console else if (Regex.IsMatch(ua, "Xbox|PLAYSTATION.3|Wii", RegexOptions.IgnoreCase)) { ret = "tv"; } // Check if user agent is a Tablet else if ((Regex.IsMatch(ua, "iP(a|ro)d", RegexOptions.IgnoreCase) || (Regex.IsMatch(ua, "tablet", RegexOptions.IgnoreCase)) && (!Regex.IsMatch(ua, "RX-34", RegexOptions.IgnoreCase)) || (Regex.IsMatch(ua, "FOLIO", RegexOptions.IgnoreCase)))) { ret = "tablet"; } // Check if user agent is an Android Tablet else if ((Regex.IsMatch(ua, "Linux", RegexOptions.IgnoreCase)) && (Regex.IsMatch(ua, "Android", RegexOptions.IgnoreCase)) && (!Regex.IsMatch(ua, "Fennec|mobi|HTC.Magic|HTCX06HT|Nexus.One|SC-02B|fone.945", RegexOptions.IgnoreCase))) { ret = "tablet"; } // Check if user agent is a Kindle or Kindle Fire else if ((Regex.IsMatch(ua, "Kindle", RegexOptions.IgnoreCase)) || (Regex.IsMatch(ua, "Mac.OS", RegexOptions.IgnoreCase)) && (Regex.IsMatch(ua, "Silk", RegexOptions.IgnoreCase))) { ret = "tablet"; } // Check if user agent is a pre Android 3.0 Tablet else if ((Regex.IsMatch(ua, @"GT-P10|SC-01C|SHW-M180S|SGH-T849|SCH-I800|SHW-M180L|SPH-P100|SGH-I987|zt180|HTC(.Flyer|\\_Flyer)|Sprint.ATP51|ViewPad7|pandigital(sprnova|nova)|Ideos.S7|Dell.Streak.7|Advent.Vega|A101IT|A70BHT|MID7015|Next2|nook", RegexOptions.IgnoreCase)) || (Regex.IsMatch(ua, "MB511", RegexOptions.IgnoreCase)) && (Regex.IsMatch(ua, "RUTEM", RegexOptions.IgnoreCase))) { ret = "tablet"; } // Check if user agent is unique Mobile User Agent else if ((Regex.IsMatch(ua, "BOLT|Fennec|Iris|Maemo|Minimo|Mobi|mowser|NetFront|Novarra|Prism|RX-34|Skyfire|Tear|XV6875|XV6975|Google.Wireless.Transcoder", RegexOptions.IgnoreCase))) { ret = "mobile"; } // Check if user agent is an odd Opera User Agent - http://goo.gl/nK90K else if ((Regex.IsMatch(ua, "Opera", RegexOptions.IgnoreCase)) && (Regex.IsMatch(ua, "Windows.NT.5", RegexOptions.IgnoreCase)) && (Regex.IsMatch(ua, @"HTC|Xda|Mini|Vario|SAMSUNG\-GT\-i8000|SAMSUNG\-SGH\-i9", RegexOptions.IgnoreCase))) { ret = "mobile"; } // Check if user agent is Windows Desktop else if ((Regex.IsMatch(ua, "Windows.(NT|XP|ME|9)")) && (!Regex.IsMatch(ua, "Phone", RegexOptions.IgnoreCase)) || (Regex.IsMatch(ua, "Win(9|.9|NT)", RegexOptions.IgnoreCase))) { ret = "desktop"; } // Check if agent is Mac Desktop else if ((Regex.IsMatch(ua, "Macintosh|PowerPC", RegexOptions.IgnoreCase)) && (!Regex.IsMatch(ua, "Silk", RegexOptions.IgnoreCase))) { ret = "desktop"; } // Check if user agent is a Linux Desktop else if ((Regex.IsMatch(ua, "Linux", RegexOptions.IgnoreCase)) && (Regex.IsMatch(ua, "X11", RegexOptions.IgnoreCase))) { ret = "desktop"; } // Check if user agent is a Solaris, SunOS, BSD Desktop else if ((Regex.IsMatch(ua, "Solaris|SunOS|BSD", RegexOptions.IgnoreCase))) { ret = "desktop"; } // Check if user agent is a Desktop BOT/Crawler/Spider else if ((Regex.IsMatch(ua, "Bot|Crawler|Spider|Yahoo|ia_archiver|Covario-IDS|findlinks|DataparkSearch|larbin|Mediapartners-Google|NG-Search|Snappy|Teoma|Jeeves|TinEye", RegexOptions.IgnoreCase)) && (!Regex.IsMatch(ua, "Mobile", RegexOptions.IgnoreCase))) { ret = "desktop"; } // Otherwise assume it is a Mobile Device else { ret = "mobile"; } return ret; }
To add display mode for tablet and TV:
DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("tablet") { ContextCondition = (context => GetDeviceType(context.GetOverriddenUserAgent()) == "tablet") }); DisplayModeProvider.Instance.Modes.Insert(1, new DefaultDisplayMode("tv") { ContextCondition = (context => GetDeviceType(context.GetOverriddenUserAgent()) == "tv") });
Note: If multiple context conditions are satisfied then app will render which appears in Display Mode order first means 0 index will have the highest priority.
Mobile View:
For mobile, If you are thinking to do something like this:
DisplayModeProvider.Instance.Modes.Insert(2, new DefaultDisplayMode("mobile") { ContextCondition = (context => GetDeviceType(context.GetOverriddenUserAgent()) == "mobile") });
OR
DisplayModeProvider.Instance.Modes.Insert(2, new DefaultDisplayMode("Mobile") { ContextCondition = (context => context.Request.Browser.IsMobileDevice) });
NO NEED to do it, mobile suffix is already inbuilt for mobile devices. By default, if you add a .mobile.cshtml view to a folder, that view will be rendered by mobile devices.
if no condition matches for any defined display mode, default desktop view is displayed.
You can test it using Mozilla User Agent Switcher Add-on.
Hope, It helps. Share your opinion or suggestion how you are implementing cross device web app.
it’s been more than 8 years. still some value points are there
Hi buddy, can we keep switching between the modes every time?
Thank you very much. Wonderfully helpful. The Kindle tablet check does not seem to work for Fire HDX versions, but it does for Fire (1st gen). I’ve looked up and found there is a little different syntax between the two types, but I’m not very good with regex. Do you have any suggestion to fix this? Thanks.
https://developer.amazon.com/appsandservices/solutions/devices/kindle-fire/specifications/04-user-agent-strings
Thanks for the code, my tablet, mobile and desktop routing now works great.
I am trying to tell in my controllers which type of device I am on by examining the DefaultDisplay.DisplayModeId which always seems to be empty. Am I completely on the wrong track?
Any help would be greatly appreciated