Tuesday, July 2, 2013

ASP.NET MVC4 - Mobile Views

In ASP.NET MVC4 you have the ability to easily present a view directed at a mobile display without requiring the use of an add on tools.  Sure, for a good mobile experience, you may choose to implement jQueryMobile or something similar, but the fact remains that it is not required with this functionality.


Mobile Experience

A good portion of visual design for mobile can come from using simple media queries to detect the current size of the users' device and render a visual experience accordingly.   Media queries within CSS are straightforward and can handle the majority of simple user experience changes.  For instance, if you wanted to change any properties of an element based on the screen width and orientation of the users' device, you could simply create some combination of the following code:
/* #### Mobile Phones Portrait #### */
@media screen and (max-device-width: 480px) and (orientation: portrait){
  /* some CSS here */
}

/* #### Mobile Phones Landscape #### */
@media screen and (max-device-width: 640px) and (orientation: landscape){
  /* some CSS here */
}

/* #### Mobile Phones Portrait or Landscape #### */
@media screen and (max-device-width: 640px){
  /* some CSS here */
}

/* #### iPhone 4+ Portrait or Landscape #### */
@media screen and (max-device-width: 480px) and (-webkit-min-device-pixel-ratio: 2){
  /* some CSS here */
}

/* #### Tablets Portrait or Landscape #### */
@media screen and (min-device-width: 768px) and (max-device-width: 1024px){
  /* some CSS here */
}

/* #### Desktops #### */
@media screen and (min-width: 1024px){
  /* some CSS here */
}

That sort of thing will go a long way, but sometimes it can lead to clutter and hard to follow CSS.


Overriding a mobile view in MVC4

With MVC 4, there is a very simple mechanism that lets you override any view for mobile browsers in general.  You can also define your own parameters for a specific mobile override, giving you the ability to build specific views for specific devices or user agents.  To provide a view that overrides for any mobile device, all you have to do is copy the view to a new file and add .Mobile to the file name. For example, to create a mobile Something view, copy Views\Home\Something.cshtml to Views\Home\Something.Mobile.cshtml.  The current context will trigger which view is pulled in a run time for a given client.  Now, you have effectively created a mobile specific view that can be visually altered for an experience geared at a mobile platform.


Custom Override Views

You can create almost any kind of custom mobile view you would like by defining a context condition and inserting into the DisplayModeProvider instance. For example, the following code will create a specific display mode based on check the user agent of the current context against 'iPhone'. Then, you add it to the list of display modes within the ApplicationStart method of the global.asax:

public class MvcApplication : System.Web.HttpApplication 
 {
 protected void Application_Start()
    {
    AreaRegistration.RegisterAllAreas();

     DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("iPhone")
        {
         ContextCondition = (ctx =>
         ctx.Request.UserAgent.IndexOf("iPhone", StringComparison.OrdinalIgnoreCase) >= 0)
        });

    //Add another one specifically for some tablets too 
    DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("Tablet")
        {
         ContextCondition = (ctx =>
         ctx.Request.UserAgent.IndexOf("iPad", StringComparison.OrdinalIgnoreCase) >= 0 ||
         ctx.Request.UserAgent.IndexOf("Android", StringComparison.OrdinalIgnoreCase) >= 0 &&
         ctx.Request.UserAgent.IndexOf("Mobile", StringComparison.OrdinalIgnoreCase) <= 0
        )
        });
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
 }

As you can see, the framework gives you the ability to create as many focused views, with as much device granularity as you see fit for your application. This will help ensure good user experiences on specific devices without having to rework existing CSS or get into switching to mobile sites.