2011-01-26 14 views
20

Vorrei suddividere i controller e le viste in librerie di classi separate in modo che possano essere riutilizzate in più applicazioni ASP.NET MVC 3. La parte relativa ai controller non era un problema quando si utilizzava un assieme separato, tuttavia ottenere il motore di visualizzazione per individuare la vista era.Condivisione di controller e visualizzazioni con più applicazioni Web

Ho finito per utilizzare Compile your asp.net mvc Razor views into a seperate dll.

C'è un modo più semplice che ho perso?

risposta

3

Date un'occhiata alle aree portatili di mvc contrib: http://www.lostechies.com/blogs/hex/archive/2009/11/01/asp-net-mvc-portable-areas-via-mvccontrib.aspx Sono stati creati appositamente per questo scopo. Se vai su quella strada, è meno codice che devi mantenere ;-)

+0

Ho visto il post di los techies. Sono sicuro che funziona bene per le persone, ma è un totale esagerato per ciò di cui ho bisogno. Messaggi con l'autobus e l'altra configurazione mi sembrano pesanti. La compilation della visualizzazione Razor è una impostazione di proprietà sulle viste (anche se su ogni vista) e il gioco è fatto. – blu

18

Ho modificato l'idea pubblicata here, per lavorare con MVC3. E 'stato abbastanza veloce e facile. L'unico inconveniente minore è che le viste condivise devono essere risorse incorporate e, pertanto, compilate.

  • Inserire le viste condivise (file .cshtml, .vbhtml) in un progetto di libreria. (Ho anche alcuni controller condivisi in questo progetto.) Se si desidera utilizzare _Layout.cshtml dall'applicazione, assicurarsi di includere un _ViewStart.cshtml, che punta ad esso, con le viste condivise.

  • Nel progetto di libreria, impostare tutte le proprietà 'Build Action di viste su Risorsa incorporata.

  • Nel progetto di libreria aggiungere il seguente codice che scriverà il contenuto delle viste in una directory tmp/Views.

.

public class EmbeddedResourceViewEngine : RazorViewEngine 
{ 
    public EmbeddedResourceViewEngine() 
    { 
     ViewLocationFormats = new[] { 
     "~/Views/{1}/{0}.aspx", 
     "~/Views/{1}/{0}.ascx", 
     "~/Views/Shared/{0}.aspx", 
     "~/Views/Shared/{0}.ascx", 
     "~/Views/{1}/{0}.cshtml", 
     "~/Views/{1}/{0}.vbhtml", 
     "~/Views/Shared/{0}.cshtml", 
     "~/Views/Shared/{0}.vbhtml", 
     "~/tmp/Views/{0}.cshtml", 
     "~/tmp/Views/{0}.vbhtml" 
    }; 
     PartialViewLocationFormats = ViewLocationFormats; 

     DumpOutViews(); 
    } 

    private static void DumpOutViews() 
    { 
     IEnumerable<string> resources = typeof(EmbeddedResourceViewEngine).Assembly.GetManifestResourceNames().Where(name => name.EndsWith(".cshtml")); 
     foreach (string res in resources) { DumpOutView(res); } 
    } 

    private static void DumpOutView(string res) 
    { 
     string rootPath = HttpContext.Current.Server.MapPath("~/tmp/Views/"); 
     if (!Directory.Exists(rootPath)) 
     { 
      Directory.CreateDirectory(rootPath); 
     } 

     Stream resStream = typeof(EmbeddedResourceViewEngine).Assembly.GetManifestResourceStream(res); 
     int lastSeparatorIdx = res.LastIndexOf('.'); 
     string extension = res.Substring(lastSeparatorIdx + 1); 
     res = res.Substring(0, lastSeparatorIdx); 
     lastSeparatorIdx = res.LastIndexOf('.'); 
     string fileName = res.Substring(lastSeparatorIdx + 1); 

     Util.SaveStreamToFile(rootPath + fileName + "." + extension, resStream); 
    } 
} 

sto usando StreamToFile scrittore di Adrian, trovato here.

  • Nei Global.asax.cs dell'applicazione aggiuntivo:

.

public static void RegisterCustomViewEngines(ViewEngineCollection viewEngines) 
{ 
    //viewEngines.Clear(); //This seemed like a bad idea to me. 
    viewEngines.Add(new EmbeddedResourceViewEngine()); 
} 

protected void Application_Start() 
{ 
    AreaRegistration.RegisterAllAreas(); 
    RegisterRoutes(RouteTable.Routes); 
    RegisterCustomViewEngines(ViewEngines.Engines); 
} 
+0

nel mio caso resStream è nullo.Possibili alcuni problemi con ReflectionPermissions (http://msdn.microsoft.com/en-us/library/xc4235zt(v=vs.110).aspx). Qualcuno ha lo stesso problema? –

+0

Questo ha funzionato davvero. La soluzione più semplice finora. Puntelli! – Exzile

3

A pochi aggiunte ottimo post di Carson Herrick ...

  1. Avrete bisogno di risolvere alcuni dei riferimenti (sarà necessario includere System.Runtime.Remoting nel progetto).

  2. Utils.SaveStreamToFile deve essere cambiato in ->

    System.Runtime.Remoting.MetadataServices.MetaData.SaveStreamToFile(resStream, rootPath + fileName + "." + extension); 
    
  3. È possibile ottenere l'errore - La vista deve derivare da WebViewPage o WebViewPage<TModel>. La risposta è qui: The view must derive from WebViewPage, or WebViewPage<TModel>

  4. Quando si distribuisce il progetto, è molto probabile che si verifichi un errore quando si carica il progetto. È necessario fornire all'APP POOL i diritti (completi) sulla cartella.

Problemi correlati