2011-01-26 15 views
20

Me gustaría distribuir mis controladores y vistas en bibliotecas de clases separadas para que puedan ser reutilizados en múltiples aplicaciones ASP.NET MVC 3. La parte de los controladores no era un problema cuando se usaba un ensamblaje separado, sin embargo, obtener el motor de vista para ubicar la vista era.Compartir controladores y vistas con múltiples aplicaciones web

Terminé usando Compile your asp.net mvc Razor views into a seperate dll.

¿Hay alguna manera más fácil que eché de menos?

Respuesta

3

Eche un vistazo a las áreas portátiles de mvc contrib: http://www.lostechies.com/blogs/hex/archive/2009/11/01/asp-net-mvc-portable-areas-via-mvccontrib.aspx Se hicieron específicamente para este propósito. Si vas por ese camino, es menos código que tienes que mantener ;-)

+0

He consultado la publicación de los techies. Estoy seguro de que funciona bien para las personas, pero es excesivo total para lo que necesito. Los mensajes con el bus y la otra configuración me parecen muy difíciles. La compilación Razor view es una configuración de propiedad en las vistas (aunque en cada vista) y eso es todo. – blu

18

He modificado la idea publicada here, para trabajar con MVC3. Fue bastante rápido y fácil. El único inconveniente menor es que las vistas compartidas deben ser recursos incrustados y, por lo tanto, compilados.

  • Ponga sus vistas compartidas (archivos .cshtml, .vbhtml) en un proyecto de biblioteca. (También tengo algunos controladores compartidos en este proyecto). Si desea utilizar _Layout.cshtml desde su aplicación, asegúrese de incluir un _ViewStart.cshtml, que lo señale, con sus vistas compartidas.

  • En el proyecto de la biblioteca, establezca todas las propiedades de Acción de compilación de sus vistas en el Recurso incrustado.

  • En el proyecto de la biblioteca, agregue el siguiente código que escribirá los contenidos de sus vistas en un directorio 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); 
    } 
} 

estoy usando escritor StreamToFile de Adrian, que se encuentra here.

  • En los Global.asax.cs de su complemento aplicación:

.

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

en mi caso resStream es nulo. Posible algunos problemas con ReflectionPermissions (http://msdn.microsoft.com/en-us/library/xc4235zt(v=vs.110).aspx). ¿Alguien tiene el mismo problema? –

+0

Esto realmente funcionó. La solución más fácil hasta el momento. ¡Accesorios! – Exzile

3

Sólo unas pocas adiciones a excelente post de Carson Herrick ...

  1. Tendrá que resolver algunas de las referencias (que tendrá que incluir en su proyecto System.Runtime.Remoting).

  2. Utils.SaveStreamToFile necesita ser cambiado a ->

    System.Runtime.Remoting.MetadataServices.MetaData.SaveStreamToFile(resStream, rootPath + fileName + "." + extension); 
    
  3. Usted puede obtener el error - La vista debe derivar de WebViewPage o WebViewPage<TModel>. La respuesta está aquí: The view must derive from WebViewPage, or WebViewPage<TModel>

  4. Al implementar el proyecto, es muy probable que obtenga un error al cargar el proyecto. Debe dar a la APLICACIÓN DE LA APLICACIÓN que está utilizando derechos (completos) en la carpeta.

Cuestiones relacionadas