Domanda

Sto tentando di implementare un motore di visualizzazione personalizzato per offrire visualizzazioni mobili basate sull'agente utente. Sto seguendo l'approccio di Scott Hanselman da questo post di blog .

Ho ereditato da WebFormsViewEngine e sovrascritto il metodo FindView nello stesso modo in cui Scott descrive nel suo blog.

Ho quindi aggiunto alcune righe al mio metodo Global.asax Application_Start per cancellare la raccolta del motore di visualizzazione e aggiungere una nuova istanza del mio motore di visualizzazione.

Dopo alcuni test sembra che MVC stia ignorando il mio motore di visualizzazione. Quando non è stato possibile trovare le visualizzazioni personalizzate in base all'agente utente del browser, ho deciso di codificare il percorso personalizzato da aggiungere alla visualizzazione e riusciva comunque a tornare alla visualizzazione predefinita. Ho impostato un punto di interruzione nel mio metodo FindView e abbastanza sicuro, non viene chiamato affatto.

Come posso far funzionare il mio motore di visualizzazione personalizzato? Qualsiasi aiuto sarà molto apprezzato.

Il mio motore di visualizzazione è simile al seguente:

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

E nel mio Global.asax:

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

Quando questa configurazione non ha funzionato, ho anche provato a semplificare il mio metodo FindView a questo:

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

E neanche quello ha funzionato. Restituiva comunque la vista predefinita. E sì, la pagina di visualizzazione e la pagina principale che dovrebbero essere trovate da quell'istruzione esistono effettivamente. Sono piuttosto sconcertato sul perché questo non funziona.

È stato utile?

Soluzione

Beh, questo è certamente imbarazzante:

Quando ho scritto il mio motore di visualizzazione seguivo il post del blog di Scott Hanselman (vedi il mio post originale per il link). Ho eliminato la mia classe di motori di visualizzazione, quindi ho deciso di copiare e incollare il codice di Scott nella mia classe e di modificarlo in base alle esigenze. Ho accidentalmente copiato il suo codice CON la definizione della classe nella mia classe creando una classe nidificata. Pertanto il mio motore di visualizzazione non conteneva effettivamente una sostituzione per il metodo FindView e naturalmente quello nella classe nidificata non sarebbe mai stato chiamato!

La lezione: quando si utilizza il codice trovato online non copiare e incollare! Digita sempre tu stesso.

Grazie a tutti coloro che hanno verificato questa domanda e hanno cercato di aiutarmi.

Adesso andrò in piedi in un angolo di vergogna e imbarazzo!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top