Skip to content
This repository has been archived by the owner on Dec 19, 2018. It is now read-only.

Question: Mobile Specific Views code? #751

Closed
Villason opened this issue May 17, 2016 · 14 comments
Closed

Question: Mobile Specific Views code? #751

Villason opened this issue May 17, 2016 · 14 comments
Labels
Milestone

Comments

@Villason
Copy link

Where can I get a glimpse of this feature before the documentation is finished?

https://docs.asp.net/en/latest/mvc/views/mobile.html

@pranavkm
Copy link
Contributor

I'm not entirely sure what would go in that document, but MvcCore does not have a direct replacement for Mvc5's DisplayModeProvider. What it does have is the ability to modify the locations in which views are searched based on a per request basis using ViewLocationExpanders. A (kinda not so useful) example of it in use is here - https://github.com/aspnet/Mvc/blob/dev/test/WebSites/RazorWebSite/Services/NonMainPageViewLocationExpander.cs.

@Eilon Eilon added the question label May 17, 2016
@Eilon Eilon added this to the Discussions milestone May 17, 2016
@Villason
Copy link
Author

@pranavkm it should be something more elaborated...

@pranavkm
Copy link
Contributor

@Villason - I don't follow what you wrote there?

@scottdorman
Copy link

@pranavkm So the real questions here are:

  • Will MvcCore be getting a replacement for DisplayModeProvider?
  • Is there currently a built-in way of detecting the platform (performing the same sort of device detection) that DisplayModeProvider did?

Yes, the view location expander would need to be used as part of this, but the question remains of how to inform the view location expander of the device type so it can determine which view location to provide.

@Eilon
Copy link
Member

Eilon commented Aug 5, 2016

There are no plans to bring back Display Modes because we would like people to instead use the new IViewLocationExpander, which we believe is better designed and more flexible.

As far as detecting platforms/browser/etc. there's no built-in way of doing this in ASP.NET Core (ASP.NET's System.Web had a browser capabilities system, but even it is somewhat out of date).

I've found some resource online that seem to have at least basic support for browser detection, such as http://detectmobilebrowsers.com/. Its code can easily be adapted to an ASP.NET Core application.

@scottdorman
Copy link

@Eilon Yes, using the new IViewLocationExpander is the right way to do this, but the question still remains of how the view location expander "knows" it needs to serve up a mobile-specific view or the "regular" one. I looked at the C# code from http://detectmobilebrowsers.com/ and it's just a big regex that looks at the user agent string.

The thing that DisplayMode (and the browser capabilities system that was in System.Web, even being out of date) provided was a "standard" way to detect and serve up a mobile view. Now, every developer who needs to do this has to write their own implementation (both the detection code and the view location expander).

Based on https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent, the recommendation is

In summary, we recommend looking for the string “Mobi” anywhere in the User Agent to detect a mobile device.

Yes, that makes it fairly trivial to write your own view location expander, but that means every developer is going to have to write their own implementation.

Ultimately, what's needed (at least for this specific issue) is the ability to detect whether or not the site is running on a mobile platform. Ideally (and probably way outside the scope) would be the ability to detect resolution and orientation, in much the same way the browser itself does for CSS media queries. If that information could be sent, then the view location expander can easily determine which view to send.

@Eilon
Copy link
Member

Eilon commented Aug 10, 2016

@scottdorman yeah I realize this isn't optimal, and it isn't easy out-of-the-box. ASP.NET 4.x had a full "Browser Capabilities" system and its strength was that it had a LOT of data about a LOT of browsers. Its weakness was that it had a LOT of data about a LOT of browsers... from 10 years ago!

Maintaining up-to-date lists of user agent mappings to capabilities is an ongoing task that gets out-of-date very quickly.

There are a couple of other discussions on this topic here:

But I have to be honest: I'm weary of adding logic to MVC/Razor if we know that within a few years it'll be out-of-date. But if we can come up with a more reliable strategy to detect these types of things, then I'm very supportive of having things built-in to the framework and to make everyone's lives easier.

@scottdorman
Copy link

@Eilon I get the problem. The browsercap stuff gets out of date very quickly, isn't easy to maintain, and really shouldn't be the responsibility of the aspnet team at all.

That being said, I like parts of the approach in the two referenced issues. It seems like something similar could be adopted where just the necessary interfaces and hooks in to the MVC routing layer (or view expander, or where ever it's most appropriate) and an out-of-the-box basic implementation (maybe just doing user agent sniffing for "mobi") are provided.

That allows more complete implementations to be created (and maintained) by interested third parties but gives them the standard hooks in to the process so it's not completely reinventing the wheel. This is, essentially, what was done with the DI approach. The out-of-the-box implementation is "good enough", but all of the other third-party DI frameworks can adapt and use the proper extensibility points to just hook in to the rest of the framework without much effort. That also keeps the aspnet team from having to maintain more advanced detection capabilities.

I'll have to look through all of the code in the PR, but on the surface it seems like an approach that could work. (Hopefully that all made sense.)

@laskoviymishka
Copy link

@scottdorman this PR is pretty old, i could update to latest source if needed.
The main idea was - abusing DI and have ability to change any step of device detection mechanism to project specific implementation. Basic implementation is good enough and even allow you to configure some different use cases (like using cookies or route part for device switching mechanism). Also one of advantages is layering - there is a bunch of IDeviceSwitcher each of them have they own device detection mechanism and it's own priority, so if you want stay on current mechanism but adding some more specific logic, you need just register services.AddTransient<IDeviceSwitcher, MyCoolSwitcher>();.
This user AgentResolver resolver is most common solution for device detection.

The code is based primarily on a list of approximately 90 well-known mobile browser UA string snippets, with a couple of special cases for Opera Mini, the W3C default delivery context and certain other Windows browsers. The code also looks to see if the browser advertises WAP capabilities as a hint.
It based on "lightweight" device resolver algorithm based on Wordpress's Mobile pack and Google's recommendations according tablet recognitions.
Original algorithm was not changed for a years, and still extremely accurate.

@laskoviymishka
Copy link

May be it worth to introduce separate project in 'aspnet' domain for device detection. So new user agents could be easily added with new version of this library

@Eilon
Copy link
Member

Eilon commented Aug 12, 2016

I think it's important to avoid having any specific user agents in the library. The problem is this:

  1. I built a web site using ASP.NET Core version x.y released in /.
  2. The site works great, works with every browser known to human kind
  3. After a few years a new browser shows up, and the site doesn't work well with that browser
  4. Now what?

If the answer to "Now what?" is that you have to recompile and redeploy the app, that just doesn't sound very great to me. It'll certainly work, but I'm not a fan of that as a solution.

And that's why I'm trying to see if there's a more generic way that requires as little knowledge as possible about user agents.

E.g. what I'd really like is if there was a proper standard around the User-Agent header where devices could simply broadcast certain well-known capabilities (touch, multi-touch, mouse, form factor, resolution, etc.). Then there's no doubt, and so long as that standard is used, everyone is happy.

@laskoviymishka
Copy link

I cannot agree with you. Your point miss one, but yet important, thing - there is no way to identify what kind of browser initiate this specific request except user agent. Provided algorithm actually is not just pointing to list of agents, it little bit smarter. You mainly talk about standard way of providing this device type in user agent. But let be honest - it out of aspnet scope :). Aspnet could only try to work with currently defined scope of user agents. Also your concern about upgrade application after several years is not very legit. Technology not stay on the same point whole time, and sometime you need to upgrade your code.

@laskoviymishka
Copy link

laskoviymishka commented Sep 30, 2016

I've published code from aspnet/Mvc#4878 as separate nuget package.
You may try it as it says here https://github.com/laskoviymishka/MvcDeviceDetector

@rynowak rynowak closed this as completed May 5, 2017
@mrnams
Copy link

mrnams commented Oct 25, 2018

Hello friends,
https://github.com/laskoviymishka/MvcDeviceDetector
Is not working

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

7 participants