Pregunta

Estoy intentando implementar un motor de vista personalizado para servir vistas móviles según el agente de usuario. Estoy siguiendo el enfoque de Scott Hanselman de esta publicación del blog .

He heredado de WebFormsViewEngine y he anulado el método FindView de la misma manera que Scott describe en su blog.

Luego agregué algunas líneas a mi método Global.asax Application_Start para borrar la colección del motor de visualización y agregar una nueva instancia de mi motor de visualización.

Después de algunas pruebas, parecería que MVC está ignorando el motor de mi vista. Cuando no pude encontrar mis vistas personalizadas en función del agente de usuario del navegador, recurrí a la codificación de la ruta personalizada para adjuntar a la vista y aún así conseguí volver a la vista predeterminada. Establecí un punto de interrupción en mi método FindView y, por supuesto, no se llama en absoluto.

¿Cómo puedo hacer que mi motor de vista personalizado funcione? Cualquier ayuda será muy apreciada.

El motor de mi vista tiene este aspecto:

public class MyViewEngine: WebFormsViewEngine
{
    public override ViewEngineResult FindView (ControllerContext controllerContext, string viewName, string masterName, bool useCache)
    {
         ViewEngineResult result = null;

         //Serve a special view for iPhones
         if (UserAgentIs(controllerContext, "iPhone"))
         {
              result = base.FindView(controllerContext, "Mobile/iPhone/" + viewName, masterName, useCache);
         }

         //If no special view is found, fall back to the default view
         if (result == null || result.View == null)
         {
              result = base.FindView(controllerContext, viewName, masterName, useCache);
         }

         return result;
    }

    private bool UserAgentIs(ControllerContext controllerContext, string userAgentToTest)
    {
         return (controllerContext.HttpContext.Request.UserAgent.IndexOf(userAgentToTest, StringComparison.OrdinalIgnoreCase) > 0);
    }
}

Y en mi Global.asax:

protected void Application_Start()
{
    RegisterRoutes(RouteTable.Routes);
    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(new MyViewEngine());
}

Cuando esta configuración no funcionó, incluso traté de simplificar mi método FindView a esto:

public override ViewEngineResult FindView (ControllerContext controllerContext, string viewName, string masterName, bool useCache)
    {
         ViewEngineResult result = null;
         result = base.FindView(controllerContext, "Mobile/iPhone/" + viewName, masterName, useCache);
         return result;
    }

Y eso tampoco funcionó. Todavía devolvió la vista predeterminada. Y sí, la página de visualización y la página maestra que debería encontrar esa declaración existen realmente. Estoy bastante perplejo en cuanto a por qué esto no está funcionando.

¿Fue útil?

Solución

Bueno, esto es ciertamente embarazoso:

Cuando escribí mi motor de visualización, estaba siguiendo la publicación del blog de Scott Hanselman (vea mi publicación original para el enlace). Decidí que mi clase de motor de vista luego decidí que simplemente copiaría y pegaría el código de Scott en mi clase y modificaría según fuera necesario. Accidentalmente copié su código CON la definición de clase en mi clase creando una clase anidada. Por lo tanto, mi motor de visualización no contenía realmente una anulación para el método FindView y, naturalmente, ¡el de la clase anidada nunca se llamaría!

La lección: cuando use el código encontrado en línea, ¡no lo copie y pegue! Siempre escríbelo usted mismo.

Gracias a todos los que verificaron esta pregunta y trataron de ayudarme.

¡Voy a pararme en la esquina de la vergüenza y la vergüenza ahora!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top