2015-07-22 12 views
6

Ho alcuni moduli con controller e viste. È fondamentalmente un'estensione per la mia applicazione web. Ogni modulo è in una libreria di classi.Come includere controller e viste da un progetto esterno in MVC6?

Desidero caricare questi assembly dalla mia applicazione Web. Ma sono senza fortuna qui.


mia struttura del file di soluzioni è come:

src 
| 
|-- Web.Common (Class Library Project) 
| |- Files like: filters, my own controller etc... 
|  
|-- WebApplication (ASP.NET5 WebSite) 
| |- wwwroot 
| |- Controllers 
| |- Views 
| |- etc... 
| 
|-- Module 1 (Class Library Project) 
| |- Controllers 
| |- Views 
| 
|-- Module 2 etc... 

Questi sono quelli che ho provato:


ho cercato di implementare il mio IViewLocationExpander

public class CustomViewLocationExpander : IViewLocationExpander 
{ 
    public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations) 
    { 
     yield return "/../Module1.Web/Views/Home/TestView.cshtml"; 
     yield return "../Module1.Web/Views/Home/TestView.cshtml"; 
     yield return "/Module1.Web/Views/Home/TestView.cshtml"; 
     yield return "~/../Module1.Web/Views/Home/TestView.cshtml"; 
    } 

    public void PopulateValues(ViewLocationExpanderContext context) 
    { 

    } 
} 

ho provato tutti i tipi di pa THS che mi sono venute in mente, ma senza fortuna :(

ottengo:

InvalidOperationException: non è stata trovata La vista 'TestView'. Le seguenti posizioni sono stati cercati:

~/Module1.Web/Vista/Home/TestView.cshtml ~ /../ Module1.Web/Vista/Home/TestView.cshtml /Module1.Web/Views/Home/ TestView.cshtml /../Module1.Web/Views/Home/TestView.cshtml


Così ho pensato che forse il default IFileProvider non guarda al di fuori percorso principale del WebApp e ha deciso di provare l'attuazione di mia possedere IFileProvider.

Ma qui non ho avuto alcun successo neanche.


Forse esiste una funzionalità per ottenere ciò chiamando alcuni metodi ASP.NET ma non lo conosco.

Qualcuno suggerisce?

risposta

8

I controller verranno caricati automaticamente. Per caricare le viste, sono necessari EmbeddedFileProvider e CompositeFileProvider, entrambi nuovi, quindi è necessario recuperarli dal feed aspnetvnext.

loro riferimento nel project.json del progetto MVC6 avvio:

"Microsoft.AspNet.FileProviders.Composite": "1.0.0-*", 
"Microsoft.AspNet.FileProviders.Embedded": "1.0.0-*", 

Aggiornare la tua registrazione servizio nel Startup.cs:

services.Configure<RazorViewEngineOptions>(options => 
    { 
     options.FileProvider = new CompositeFileProvider(
      new EmbeddedFileProvider(
       typeof(BooksController).GetTypeInfo().Assembly, 
       "BookStore.Portal" // your external assembly's base namespace 
      ), 
      options.FileProvider 
     ); 
    }); 

In project.json della vostra assemblea esterna, aggiungere questo:

"resource": "Views/**" 

Qui ' s un'implementazione di esempio che puoi clonare ed eseguire per vederlo in azione: https://github.com/johnnyoshika/mvc6-view-components

+0

Mi piacerebbe avere più assiemi che contribuiscono a visualizzazioni e logica del controllore a un'app web centrale. Qualche idea su come indirizzare un array di FileProviders? – Matthew

+1

@Matthew, 'CompositeFileProvider' accetta una raccolta di' FileProviders', quindi è possibile registrarne il numero desiderato. 'new CompositeFileProvider (EmbeddedFileProvider, EmbeddedFileProvider, EmbeddedFileProvider, ecc.)'. –

+0

@Matthew, se guardi all'implementazione di esempio che ho collegato sopra, vedrai un esempio in cui estraggo le viste da più assiemi. Ecco il codice rilevante: https://github.com/johnnyoshika/mvc6-view-components/blob/master/Web/Startup.cs#L27 –

2

penso che le opinioni devono vivere nel web app principale unless you want to use some non-standard 3rd party solutions

La mia comprensione è che in beta7 saremo in grado di confezionare vista e altri file contenuti in un NuGet libreria di classi che si crea quando si costruisce la classe libreria con VS 2015. Ma la mia comprensione è che quando l'app web principale aggiunge una dipendenza a tale nuget, i file di contenuto verranno aggiunti all'applicazione web principale, cioè le mie viste verranno aggiunte sotto Views/MyModule o qualcosa di simile sono utilizzabili dall'applicazione web principale.

Almeno questo è l'approccio che mi aspetto di adottare in modo che le mie opinioni possano essere lette e/o modificate in seguito da altri.

Penso che l'altra opzione sia precompilare le viste in modo tale che non esistano sul disco come file .cshtml ma questo renderebbe più difficile per gli altri personalizzare le visualizzazioni.

+0

Vogliamo spedire i nostri moduli esternamente. Dovrebbero essere aggiungibili o rimovibili copiando o eliminando la sua cartella. Quindi non vogliamo renderli parte del progetto principale. Non vogliamo nemmeno renderli un'applicazione web autonoma. – Yves

+0

Ho trovato temporaneamente una soluzione (anche pubblicata qui) e l'utilizzo al momento. Aspetterò la funzione beta7 per provarlo. – Yves

2

ho raggiunto questo utilizzando IViewLocationExpander e PhysicalFileProvider

ho usato IFileProvider del motore del rasoio per impostare il percorso principale della cartella src. Aggiungendo il nome dell'assembly, ottengo il percorso del percorso root del progetto.

public class MultiAssemblyViewLocationExpander : IViewLocationExpander 
{ 
    public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations) 
    { 
     var actionContext = (ResultExecutingContext)context.ActionContext; 
     var assembly = actionContext.Controller.GetType().Assembly; 
     var assemblyName = assembly.GetName().Name; 

     foreach (var viewLocation in viewLocations) 
      yield return "/" + assemblyName + viewLocation; 
    } 

    public void PopulateValues(ViewLocationExpanderContext context) 
    { 

    } 
} 

E in ConfigureServices metodo:

services.Configure<RazorViewEngineOptions>(options => 
{ 
    options.FileProvider = new PhysicalFileProvider(HostingEnvironment.WebRootPath + "..\\..\\"); 
    options.ViewLocationExpanders.Add(new MultiAssemblyViewLocationExpander()); 
}); 

PS: Non ho prove su questo un'applicazione pubblicata. Ma sarà facile risolverlo se si verificano alcuni problemi di percorso;)

Problemi correlati