Question

J'essaie d'implémenter un moteur de vue personnalisé pour servir les vues mobiles basées sur l'agent utilisateur. Je suis l'approche de Scott Hanselman d'après ce billet de blog .

J'ai hérité de WebFormsViewEngine et substitué la méthode FindView de la même manière que Scott décrit dans son blog.

J'ai ensuite ajouté quelques lignes à ma méthode Global.asax Application_Start pour effacer la collection du moteur de vue et ajouter une nouvelle instance de mon moteur de vue.

Après quelques tests, il semblerait que MVC ignore mon moteur de vue. Quand il n'a pas réussi à trouver mes vues personnalisées basées sur l'agent utilisateur du navigateur, j'ai codé en dur le chemin personnalisé à ajouter à la vue et il a quand même réussi à revenir à la vue par défaut. J'ai défini un point d'arrêt dans ma méthode FindView et, bien sûr, il n'est pas appelé du tout.

Comment puis-je faire fonctionner mon moteur d'affichage personnalisé? Toute aide sera très appréciée.

Mon moteur de vue ressemble à ceci:

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);
    }
}

Et dans mon Global.asax:

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

Lorsque cette configuration ne fonctionnait pas, j'ai même essayé de simplifier ma méthode FindView:

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;
    }

Et cela n'a pas fonctionné non plus. Il a quand même retourné la vue par défaut. Et oui, la page de vue et la page maître qui devraient être trouvées par cette déclaration existent réellement. Je ne comprends pas très bien pourquoi cela ne fonctionne pas.

Était-ce utile?

La solution

Eh bien, c’est certainement embarrassant:

Lorsque j'ai écrit mon moteur de visualisation, je suivais le message de Scott Hanselman sur le blog (voir le message d'origine dans mon message). J'ai détaillé ma classe de moteur de vue, puis j'ai décidé de copier et coller le code de Scott dans ma classe et de le modifier au besoin. J'ai accidentellement copié son code AVEC la définition de classe dans ma classe en créant une classe imbriquée. Par conséquent, mon moteur de vue ne contenait pas de substitution pour la méthode FindView et, naturellement, celui de la classe imbriquée ne serait jamais appelé!

La leçon: lorsque vous utilisez du code trouvé en ligne, ne copiez pas et ne collez pas! Tapez toujours vous-même.

Merci à tous ceux qui ont consulté cette question et ont essayé de m'aider.

Je vais aller maintenant dans le coin de la honte et de l'embarras maintenant!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top