2012-03-08 540 views
32

Estoy probando las nuevas características de ASP.NET MVC 4 Mobile. Hice una aplicación simple con solo un controlador (HomeController) y una vista (índice). También agregué una versión móvil de la vista de índice.ASP.NET MVC 4 Mobile Características

Views/Home/Index.cshtml 
Views/Home/Index.Mobile.cshtml 

Al lanzar la aplicación en un navegador de escritorio se muestra la vista normal como se esperaba, sin embargo cuando inicio la aplicación en el Opera Mobile Emulator como un Galaxy S de Samsung, sigo teniendo la vista normal y no la versión móvil.

la cadena de agente de usuario enviado desde el emulador tiene el siguiente aspecto:

Opera/9.80 (Windows NT 6.1; Opera Mobi/23731; U; en) Presto/2.9.201 Version/11.50 

¿Alguna idea de por qué esto no está funcionando?

actualización Gracias a @nemesv yo era capaz de resolver el problema, aquí está mi solución actual, es de esperar que cubrirá la mayoría de los escenarios móviles.

public class MobileDisplayMode : DefaultDisplayMode 
{ 
    private readonly StringCollection _useragenStringPartialIdentifiers = new StringCollection 
    { 
     "Android", 
     "Mobile", 
     "Opera Mobi", 
     "Samsung", 
     "HTC", 
     "Nokia", 
     "Ericsson", 
     "SonyEricsson", 
     "iPhone" 
    }; 

    public MobileDisplayMode() : base("Mobile") 
    { 
     ContextCondition = (context => IsMobile(context.GetOverriddenUserAgent())); 
    } 

    private bool IsMobile(string useragentString) 
    { 
     return _useragenStringPartialIdentifiers.Cast<string>() 
        .Any(val => useragentString.IndexOf(val, StringComparison.InvariantCultureIgnoreCase) >= 0); 
    } 
} 

Y i Global.asax

DisplayModeProvider.Instance.Modes.Insert(0, new MobileDisplayMode()); 
+2

salvavidas. es realmente estúpido que el tutorial no diga esto. Se siente tan medio asno desde el lado de Microsoft. Usualmente están a punto con sus tutoriales. –

+1

Gracias, aunque StringCollection parece ser una de las clases más inútiles de la historia. No solo no ofrece nada en este ejemplo de código, ni en el rendimiento, debe escribir código adicional (Cast ) por el placer de usarlo. Reemplazarlo con la lista y vivir felizmente después de – PandaWood

Respuesta

28

ASP.Net (en realidad la clase HttpBrowserCapabilitiesBase) no reconoce el emulador de Opera Mobile como un navegador móvil.

Puede verificar esto en cualquier acción del controlador: HttpContext.Request.Browser.IsMobileDevice devolverá false para el navegador Opera Mobile.

Dado que el built in DefaultDisplayMode utiliza el siguiente método para verificar los navegadores móviles, debe registrar su DisplayMode personalizado que reconoce correctamente Opera Mobile.

Para hacer esto es necesario añadir esto a la Global.asax Application_Start:

DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("Mobile") 
{ 
    ContextCondition = (context => context.GetOverriddenUserAgent() 
     .IndexOf("Opera Mobi", StringComparison.OrdinalIgnoreCase) >= 0) 
}); 
+1

¡Gracias! Eso funcionó muy bien! como resultado, tampoco reconoció el navegador predeterminado en un Samsung Galaxy S. No he podido averiguar exactamente cómo el marco MVC 4 valida la cadena del agente de usuario. Implementé una clase que, con suerte, cubrirá la mayoría de los escenarios. He actualizado la pregunta con ese código. – Pelle

+5

Debe consultar la herramienta gratuita de escritorio Keynote Mite para probar y verificar la aplicación de contenido web móvil. Es una excelente herramienta de prueba móvil. http://mite.keynote.com/ –

+0

Gracias por la sugerencia, lo haré – Pelle

0

una solución para todos los móviles sin necesidad de especificar todos los nombres navegador será así ...

protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 
     WebApiConfig.Register(GlobalConfiguration.Configuration); 
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 
     BundleConfig.RegisterBundles(BundleTable.Bundles); 
     AuthConfig.RegisterAuth(); 

     DisplayModeProvider.Instance.Modes.Insert(0, 
      new DefaultDisplayMode("Mobile") 
      { 
       ContextCondition = (ctx => (
        (ctx.GetOverriddenUserAgent() != null) && ctx.Request.Browser.IsMobileDevice 
      )) 
      }); 
    }  
+1

En realidad, esto no funcionará, según http://stackoverflow.com/questions/12710026/how-does-mvc4-detect-a-mobile-browser el mismo código que hace que Request.Browser.IsMobileDevice detectar un dispositivo móvil es el mismo control que se realiza al elegir una vista móvil para procesar. – JonVD