Ho problemi a risolvere 404 risposte nel mio progetto Asp.Net MVC 4. È stato creato con il targeting VS2012 4.5.404 su controller in gruppi esterni
Ho viste e controller precompilati incorporati in DLL autonome. Sono in grado di caricare dinamicamente le DLL e ispezionarle dal mio progetto principale, invocando anche metodi su di esse; tuttavia, sembra che MVC Framework non sia a conoscenza dei controller. Sono qui vicino, ma manca qualcosa.
Sfondo sui controller e viste
controllori sono costruiti in un progetto MVC stand-alone e ereditare da Controller
. Niente di troppo interessante in corso lì. Le viste utilizzano RazorGenerator e diventano classi che vivono nel progetto.
L'output del progetto è una DLL che contiene correttamente i controller e le viste.
Le DLL implementano un'interfaccia specifica, la chiameremo IPlugin
, in una classe separata (non parte di un controller) nella libreria.
Caricamento le DLL
Esecuzione come admin in Visual Studio compilo la mia applicazione, che è ospitato in IIS. Con il progetto creato, inserisco una DLL plugin nella mia directory "Plugin". Senza debug (questo diventa importante in seguito), apro IE e navigo nel sito. Nota che a questo punto l'app è stata creata, ma non viene mai eseguita, quindi gli eventi di avvio verranno attivati. Tutto qui è ancora coerente se riciclo il pool di app.
Ho una classe Startup
con due metodi, PreStart
e PostStart
e richiamare i metodi usando WebActivator.PreApplicationStartMethod
e WebActivator.PostApplicationStartMethod
rispettivamente.
PreStart
è dove faccio la seguente:
- ottenere un elenco di tutte le DLL plugin nella mia cartella "Plugins"
- Copia tutti i plugin per
AppDomain.CurrentDomain.DynamicDirectory
- Caricare il tipo ... se contiene un
IPlugin
ho poi- aggiungere l'assembly al BuildManager
- chiamata alcuni dei metodi della classe che imp ELEMENTI IPlugin
In 'poststart' Faccio questo pezzo di codice (basato sul codice da RazorGenerator.Mvc):
foreach (var assembly in Modules.Select(m=>m.Value))
{
var engine = new PrecompiledMvcEngine(assembly)
{
UsePhysicalViewsIfNewer = HttpContext.Current.Request.IsLocal
};
ViewEngines.Engines.Insert(0, engine);
VirtualPathFactoryManager.RegisterVirtualPathFactory(engine);
}
Modules
in questo contesto è una coppia chiave/valore in cui il i valori sono gli assembly caricati. Lo scopo di questo codice è assicurarsi che MVC sia a conoscenza delle visualizzazioni aggiungendo un motore di visualizzazione per ogni assembly che sa come risolvere le viste (questo fa parte di RazorGenerator).
Come lo so sono vicino (ma chiaramente Mancando il sigaro)
IPlugin
definisce un metodo chiamato RegisterRoutes
dove, avete indovinato, percorsi devono essere registrati per coloro che implementa l'interfaccia. Io chiamo questo metodo in PreStart
e le rotte sono aggiunte - Ho verificato che queste esistano nella mia tabella dei percorsi. Per esempio, su un percorso definito nel mio plug-in, creata attraverso l'invocazione dinamica del metodo durante la PreStart
, vedo qualcosa di simile a questo come un DataToken in sede di esame miei percorsi:
Namespaces = Plugin.Name.Controllers
Quindi, il percorso viene registrato, il l'assembly è stato caricato, ho verificato che la DLL sia correttamente copiata nella DynamicDirectory dell'AppDomain. Sono in grado di invocare membri di classi caricate dinamicamente in fase di runtime. Ma quando navigo verso l'URL che corrisponde alla route ottengo un 404. Questo è non un "impossibile trovare la vista" YSOD, è più simile a non trovare il controller affatto.
Ecco la parte che mi confonde da me: se, a questo punto, senza fare nulla, torno a Visual Studio e prendo F5 ... tutto funziona.
È come se Visual Studio stia diventando consapevole del controller in qualche modo che non riesco a identificare e MVC Framework si sta occupando di esso.
Infine, una domanda
Quello che mi manca, e come faccio ad avere il framework MVC di essere a conoscenza del mio controller?
E hey, a questo punto, se stai ancora leggendo questo, grazie. :)
1. VS sta usando Cassini? Prova a cambiarlo in IIS Express e controlla se continua a funzionare correttamente. 2. Provare a installare [RouteDebugger] (http://nuget.org/packages/routedebugger) - potrebbe darti qualche indizio se i percorsi vengono registrati correttamente su IIS – Pranav
Grazie a @Pranav, ma è già su IIS. Il debugger di route mostra che i percorsi funzionano. – MisterJames
Potrebbe essere un problema? http://stackoverflow.com/questions/14971895/using-precompiledmvcengine-findview-throws-invalidoperationexception-and-looks-f – Tengiz