Wednesday 24 April 2013

Device Detection in ASP.NET MVC 4

In this example I am going to demonstrate the MVC 4 Device detection libraries. ASP.NET MVC 4 introduces Display Modes to which allows you to write device specific application. This is a newly introduced feature of ASP.NET MVC 4. This selects a view depending on the browser making the request, which means you can target specific devices and present the user device specific customized pages.

By default Display Mode Provider implements the mobile view;

clip_image002

You just need to provide the mobile specific pages to your application by just creating a pagename.mobile.cshtml and you are done.

clip_image004

I have done few customizations in my Web and Mobile pages just to display the requesting browser UserAgent and to identify if this is a page for web or mobile. Now let’s run the application and see output.

I have used Mozilla User Agent Switcher Add-on here to switch between the browsers. clip_image002[4]

Page displayed by default User Agent (Desktop)

clip_image004[4]

Page displayed when I select the iPhone as User Agent.

You can notice here that this all achieved without even writing a piece of code till now, with just the addition of .mobile.cshtml page I am able to achieve this.

But in real world things are not so straight forward, we have plenty of devices emerging every year and we have to provide device specific pages for each one of those devices with very little or negligible development effort and of course with minimal code changes.

With display mode provider we cannot just add a device specific pages instead we can also specify Browser specific page, OS Specific pages and even Vendor specific pages yes that is true. The only thing what we need to know is the identifiable user agent which provides us enough information about the Browser, Device, OS, etc information.

Now let me add some customization to my code for iPhone. In this case I am going to display a page which is specific to only iPhone. First of all let’s create a page for iPhone as Index.iphone.cshtml

clip_image006

You can and add some code which will tell us on runtime that this page is only meant for iPhone. Now add few lines of code in Global.ascx.cs file. Here in these codes I have added entry into the DisplayModeProvider for iPhone, this will tell the application that whenever you see the iPhone text in the browser UserAgent, just take the user to Index.iphone.cshtml page.

DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("iphone")



{



     ContextCondition = (context => context.GetOverriddenUserAgent().IndexOf("iphone", StringComparison.OrdinalIgnoreCase) >= 0)



});






Now let’s see the output at runtime,



clip_image002[8]



Here in the screen above you can see that I have got an additional entry for iphone in DisplayModeProvider collection, and the output screen I got from the code is as below:



clip_image004[9]



Similarly you can add as many entries as you wish, and for e.g if you want to have same page for multiple devices like for iPad and Tablet I want to display Index.tablet.cshtml page, then you can write the codes as:





DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("tablet")



{



    ContextCondition = (context => context.GetOverriddenUserAgent().IndexOf("tablet", StringComparison.OrdinalIgnoreCase) >= 0



    || context.GetOverriddenUserAgent().IndexOf("ipad", StringComparison.OrdinalIgnoreCase) >= 0)



});




So you can see DisplayModeProvider is fully customizable and extensible based on your requirement. But the catch is you need to have a complete list of Browser User Agents to handle virtually all the possible devices programmatically from your code. For I came across one very interesting link from Tech Brij Blog, including the code provided in this blog will complete this example and you can have a complete working example of the device detection using MVC 4





private static 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;



}




The code above covers a very exhaustive list of devices/browsers/OS which are available. This is a reengineered version of Categorizr(A device detection script) provided with premium version of 51degrees.mobi



The function provided above uses RegEx library to find the matching content in the Browser User Agent string and based on the match it returns the device type as string. The Code below calls the GetDevice function to get the device type string to the ContextCondition as either tablet, mobile or 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")



});



DisplayModeProvider.Instance.Modes.Insert(2, new DefaultDisplayMode("mobile")



{



   ContextCondition = (context => GetDeviceType(context.GetOverriddenUserAgent()) == "mobile")



}); 




This is just a small sample of the Display Mode Provided packaged with ASP.NET MVC 4, other links which might help you in understanding the overall concepts are:



References:



http://www.campusmvp.net/displaymodes-in-mvc-4/



http://msdn.microsoft.com/en-us/library/system.web.webpages.displaymodeprovider(v=vs.111).aspx



Sample project with the implementation can be downloaded from here:



https://docs.google.com/file/d/0BzIjFd_Ps-MSQThrTklrbXZOQlU/edit?usp=sharing

Share:

Monday 15 April 2013

Play Notification Sound using Jquery.

I received lots tutorial requests from my readers that asked to me, how to play a notification sound on website chat?. We implemented this in a simple chat box application using Jquery and HTML5 audio tag, it is just five lines of code. Use Modernizer library for Internet Explorer HTML5 support, please turn on the volume and try this live demo.

Play Notification Sound using Jquery.

Read more »
Share:

Thursday 4 April 2013

AngularJS 1.0.6 universal-irreversibility and 1.1.4 quantum-manipulation released!

Today we are announcing two sweet AngularJS releases!

Just as with previous 1.0.x releases, AngularJS 1.0.6 universal-irreversibility brings a bunch of bug fixes and lots of documentation improvements.

AngularJS 1.1.4 quantum-manipulation is a beast packed with highly requested features like animation support, more flexible (and faster) ngRepeat directive, powerful promise-based http request interceptors, support for dynamically generated directive templates and initial batch of mobile/touch support.

Special thanks to Dave Geddes for helping us migrate our build system from Rake to Grunt, this means that building AngularJS from sources is now much easier for many folks and it's possible to build Angular even on Windows (if you really have to ;-) ).

For full details in both these releases, see the changelog.

We thought that animations would be the feature that would attract most of the attention, so to give you background on many design decisions that we made when implementing this feature, MiÅ¡ko gave a presentation on this topic yesterday at GDG Silicon Valley. Check out the video recording from this event to learn more as well as this animations demo app and an in-depth write up by Matias from yearofmoo.com.



Our appreciation to the community contributors responsible for the PRs in these releases: Alexander Shtuchkin, Andrew McLeod, Arlen Christian Mart Cuss, Braden Shepherdson, Bruno Coelho,  Christian Vuerings, Ciro Nunes, Dave Geddes, David Chang, Felipe Lahti, Gert Goet, Jamie Mason, Jason Als, Jason Morrison, Javier Mendiara Cañardo, Julie, Jørgen Borgesen, Lucas Galfasó, Luis Ramón López, Manuel Braun, Mark Chapman, Mark Nadig, Matias Niemelä, Matt Ginzton, Matthew, McComb, Niel de la Rouviere, Pascal Borreli, Pawel Kozlowski, Shyam Seshadri, Srinivas Kusunam, Steven Davidson, Sujeet Pillai, Sylvester Keil, Thibault Leruitte, Vineet Kumar, William Bagayoko, danilsomsikov, zeflasher.

Links

1.0.6 universal-irreversibility (stable branch)

Google CDN
Downloads
angular-seed
Complete Changelog
Documentation

1.1.4 quantum-manipulation (unstable branch)

Google CDN
Downloads
Complete Changelog
Documentation
Share:

Tuesday 2 April 2013

HTML5 Template Design for Blog.

This is right time to adopt HTML5 semantic markup tags into your website design. W3C has conducted a study of over billion websites and found that the most of common div IDs and classes are footer, header, menu, content, title and nav. HTML5 semantic markup elements that can convey the purpose of the element to developers, browser and search spider algorithms.

HTML5 Template Design for Blog.

Read more »
Share: