📜 ⬆️ ⬇️

ASP.NET MVC 4 Mobile Features Obsolete Faster than Appeared

What are Mobile Features in ASP.NET MVC 4


ASP.NET MVC 4 came out with a very expected and long-awaited new feature - what is in English called Mobile Features - support for mobile devices. By and large, the name was immediately surprised, since it differs slightly from the technical description of the innovation. But promotion is promotion. All references to page templates (layout) with HTML 5 support, specifying viewport, CSS media - all this has no direct relation to the MVC framework.

Only two points can be attributed to the new features of the framework itself:

And here it is immediately worth noting that the word “mobile” is mentioned exclusively for promotional purposes. MVC 4 allows you to create multiple View for each of the required pages and determine for which browser each of them should be displayed. That is, the possibilities are in no way limited to mobile browsers.

All ingenious is simple - “hook” in ViewEngine


The implementation of this feature is very simple. This is just a “hook” in ViewEngine.
')
You make different pages (Views) for different devices or browsers. Name the files by adding the keyword:

Specify the criterion by which the desired View will be selected - using the DisplayModeProvider, specify the desired DefaultDisplayMode with the desired name.

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

In runtime, when the controller's method has been processed, the prepared ViewResult is passed to the View Engine, the DisplayModeProvider conditions are checked, it changes the name of the View file to be loaded.

Can we really use it?


Of course we can. But only in very simple cases. The main disadvantage is that all the Views you make for the page are processed by the same controller method. Sooner or later, it becomes a problem.

The time has already come when the website should support browsers not only on desktop computers, laptops and mobile devices, but also on TVs. And to mobile devices include ordinary phones, smartphones and tablet computers. And you will agree - if the appearance on the tablet and smartphone can still be the same, with the same JavaScript widgets, then for ordinary cell phones, of which there are still many, it is difficult to provide the same presentation and the same Web UI capabilities.

Support simultaneously smartphones and tablets at a glance does not look so complicated - the difference in screen size. But in a larger area you can place more information or more user-defined functions, and not just increase the size of the images.

TV support looks like a very simple task. Full HD means the same screen size in pixels. But the pros are over.

It turns out that if your site was opened from TV, it could be opened in browsers on:

To make the version of the site equally convenient for all these devices is not very realistic. If you want to take advantage of all the additional features that these devices provide you as developers, then doing it in one version of the site becomes not rational. And some opportunities, believe, are worth to use them.

For example, the usual Internet Explorer works on XBOX, the screen width is quite sufficient to work with the usual desktop version of the site, but the user is forced to move the cursor on the joystick. In order to press a button on the screen, he needs to hover the cursor on it and press the button on the joystick. It becomes obvious that a more suitable interface is an interface for tablets, with large rectangular buttons. Comboboxes are also not convenient. Scrolling through the page on the joystick is quite convenient.

On SmartTV, you will have to rely on the fact that there is no cursor and the user runs along the buttons and inputs on the page by pressing the up / down / left / right buttons on the remote. In order to support other buttons on the console that simplify navigation, you will have to read the documentation from the SDK and write JavaScript specific to a particular device - the key codes are different.

And this is only if you start looking at televisions. There are also many interesting things with smartphones and tablets, but this is a more common and often discussed topic.

It is necessary to start working in this direction and very quickly the question arises that the versions of sites for desktops, mobile devices and TVs should be different. And should differ not only in View. There should be different models, which means it is best when different methods of controllers work with them.

What can be offered in return?


It is clear that the simplest thing is to immediately make different sites for different devices and redirect to the right one. Discard such a solution as too simple. You can roll back to this option at any time.

Of course, you can make different methods for different devices in the same controller, but I would like a more convenient and beautiful solution.

Given the architecture of ASP.NET MVC 4, there is only one option. Inside the MVC application (project), each version of the site must be executed in its own Area. According to the User Agent String, we can determine from which device / browser the request arrives and send it to the desired Area.

To forward to the desired Area, you need to add a restriction (Constraint) for each route (Route) in the routing table.

The disadvantage of this approach is that such a restriction must be remembered to be added to all routes.

For example, if we made the Area to which you want to redirect everyone with the Chrome browser, then Area Registration will look like this:

  public class ChromeAreaRegistration : AreaRegistration { public override string AreaName { get { return "Chrome"; } } public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "Chrome_default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new { isChromeBrowser = new IsChromeConstraint() } ); } } 

In this case, the restriction will look like this:

  public class IsChromeConstraint : IRouteConstraint { public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { string userAgent = httpContext.Request.UserAgent; if (string.IsNullOrWhiteSpace(userAgent)) { return false; } return userAgent.Contains("Chrome"); } } 

At the same time, we have a main Area where all other browsers except Chrome should go.

  public class DesktopAreaRegistration : AreaRegistration { public override string AreaName { get { return "Desktop"; } } public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "Desktop_default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new { isNotChromeBrowser = new IsNotChromeConstraint() } ); } } 

in it, we also need to use a restriction that filters browsers cutting off Chrome:

  public class IsNotChromeConstraint : IRouteConstraint { public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { string userAgent = httpContext.Request.UserAgent; if (string.IsNullOrWhiteSpace(userAgent)) { return false; } return !userAgent.Contains("Chrome"); } } 

It is necessary to set restrictions for all routes in all Area, despite the fact that routes in runtime are viewed from top to bottom. The fact is that the procedure for registering an AreaRegistration at random is random. This can be avoided by registering the routes of all Area in one place - in Global.asax - clearly indicating their order. Then you can guarantee that the check on Chrome browser will always happen first.

P.S


If you get bored with it, you can always easily bring each Area into a separate application and host on different domains.

Source: https://habr.com/ru/post/163225/


All Articles