Display Modes in ASP.NET MVC 4
This is my first article after the availability of ASP.NET MVC 4 RTM & Visual Studio 2012 RTM.
Here is the brand new Visual Studio 2012 logo:
ASP.NET MVC 4 includes set of features for mobile development, one of them is Display Modes.
The new Display Modes feature lets an application select views depending on the browser that’s making the request. For example, if a desktop browser requests the Home page, the application might use the ViewsHomeIndex.cshtml template. If a mobile browser requests the Home page, the application might return the ViewsHomeIndex.mobile.cshtml template.
Let say I have a page Home.cshtml in my website, whoever is the client (desktop browser/mobile browser) requesting for this page, my application will render the same page. But I want to provide good user experience to user so I going to design different pages for each type of browser. One for all desktop browsers (Home.cshtml), each for major mobile browsers (iPhone – iHome.cshtml, Windows Phone – WpHome.cshtml etc…)
We should write lot of code for doing this, first we should detect the requesting browser (using user agent strings), Locate the requested page & finally redirecting to respective page depending on the browser. Lot of mess with multiple if else conditions for each request. We should do the same for all the pages in web site.
Now we can do this with simply with one line of code for each browser using Display Modes in MVC 4.
Using display modes involves in 2 steps:
- We should register Display Mode with a suffix for particular browser using “DefaultDisplayMode”e class in Application_Start() method in the Global.asax file.
- View name for particular browser should be appended with suffix mentioned in first step.
Not only Views, Layouts and Partial Views can also be overridden for particular browser types.
If your ViewsShared folder contains both the _Layout.cshtml and _Layout.mobile.cshtml templates, by default the application will use _Layout.mobile.cshtml during requests from mobile browsers and _Layout.cshtml during other requests.
If a folder contains both _Login.cshtml and _Login.mobile.cshtml, the instruction @Html.Partial(“_Login”) will render _Login.mobile.cshtml during requests from mobile browsers and _Login.cshtml during other requests.
Out of the box ASP.NET MVC 4 ships with 2 Display Modes:
using System.Web.Http; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; using System.Web.WebPages; namespace DisplayModesSample { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); var displayModes = DisplayModeProvider.Instance.Modes; WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); AuthConfig.RegisterAuth(); } } }
- Desktop browsers (without any suffix. e.g.: Index.cshtml, _Layout.cshtml)
- Mobile browsers (with a suffix “Mobile”. e.g.: Index.Mobile.cshtml, _Layout.Mobile.cshtml)
If you want design different pages for different mobile device browsers (any different browsers) and render them depending on the browser requesting. To handle these requests you can register custom display modes. We can do that using DisplayModeProvider.Instance.Modes.Insert(int index, IDisplayMode item) method.
We have an implementation for IDisplayMode interface that is DefaultDisplayMode class. In DefaultDisplayMode class constructor we should provide a suffix and then should set a property named “ContextCondition” for detecting the browser.
Here is the sample code:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("WP") { ContextCondition = (context => context.GetOverriddenUserAgent(). IndexOf("Windows Phone OS",StringComparison.OrdinalIgnoreCase) >= 0) }); DisplayModeProvider.Instance.Modes.Insert(1, new DefaultDisplayMode("iPhone") { ContextCondition = (context => context.GetOverriddenUserAgent(). IndexOf("iPhone", StringComparison.OrdinalIgnoreCase) >= 0) }); DisplayModeProvider.Instance.Modes.Insert(2, new DefaultDisplayMode("Android") { ContextCondition = (context => context.GetOverriddenUserAgent(). IndexOf("Android", StringComparison.OrdinalIgnoreCase) >= 0) }); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); AuthConfig.RegisterAuth(); }
Let’s see the Display Modes in action (watch the video):
Good article …Very clear explanation