Autor en Google+
Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET, ASP.NET Core, MVC, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

12 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET, ASP.NET Core, MVC, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 20 de noviembre de 2018
ASP.NET Core MVCSeguramente habréis notado que en proyectos ASP.NET Core 2.1 la compilación de las vistas funciona de forma ligeramente diferente a como se hacía en versiones anteriores. Hasta ahora las vistas sólo eran compiladas al publicar el proyecto pero, a partir de esta versión, este proceso se realizará antes, durante la compilación.

En este artículo vamos a ver cómo aprovechar las ventajas de la precompilación, y al mismo tiempo mantener la flexibilidad que nos ofrece la compilación en tiempo de ejecución que tradicionalmente hemos disfrutado en proyectos ASP.NET y ASP.NET Core.

A partir de ASP.NET Core 2.1, cuando compilemos normalmente nuestros proyectos, en el directorio /bin encontraremos, además de los archivos habituales, un ensamblado llamado [MyProjectName].Views.dll con el resultado de la compilación de las vistas Razor:

Directorio de salida de compilación, con el ensamblado de las vistas

Esto es buena cosa, sin duda. El hecho de compilar las vistas hará posible que detectemos antes los errores de programación, y normalmente los tiempos de compilación son tan rápidos que ni notaremos que ese proceso se está realizando. Además, al desplegar el proyecto, el arranque de la aplicación será más rápido porque no será necesario compilar las vistas al vuelo cuando los usuarios accedan a ellas.

Por otra parte, dado que el resultado de la compilación de las vistas ya lo tenemos en la carpeta de binarios en forma de ensamblado, al publicar el proyecto no se incluirá el contenido de las carpetas /Views, /Pages u otras relacionadas con las plantillas Razor:
Carpeta de resultados de publicación, donde no aparecen las carpetas de vistas

Gracias a esto, el paquete de publicación será más pequeño y las operaciones de despliegue serán más rápidas, porque hay muchos menos archivos que gestionar.

Sin embargo, al no existir en el servidor, dejaremos de tener la capacidad de actualizar directamente los archivos Razor, una característica muy socorrida cuando detectamos pequeños fallos o queremos introducir mejoras que no requieren un despliegue completo.

Lo que realmente estaría bien sería tener lo mejor de estos dos mundos, es decir, disponer al mismo tiempo de las ventajas de publicar las vistas precompiladas, pero a la vez mantener la posibilidad de actualizarlas directamente en el servidor y que éstas fueran recompiladas automáticamente sin necesidad de subir todo el proyecto.

Para conseguirlo, necesitaremos dos cosas:
  • Primero, hacer que en el paquete de publicación se incluyan los archivos de vista.
     
  • Segundo, hacer que las vistas puedan sean recompiladas de forma automática cuando se detecten cambios en ellas.

1. Incluir las vistas en el paquete de publicación

Para que las vistas de una aplicación MVC sean incluidas a la hora de generar el paquete de publicación, basta con añadir el siguiente código al archivo .csproj de nuestro proyecto:
<ItemGroup>
  <_CustomFiles Include="$(MSBuildProjectDirectory)/views/**/*" />
  <DotnetPublishFiles Include="@(_CustomFiles)">
    <DestinationRelativePath>views/%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
  </DotnetPublishFiles>
</ItemGroup>
Si además queremos incluir las páginas Razor, presentes por convención en la carpeta "/Pages" del proyecto, debemos añadir adicionalmente el siguiente bloque:
<ItemGroup>
  <_CustomFiles Include="$(MSBuildProjectDirectory)/pages/**/*" />
  <DotnetPublishFiles Include="@(_CustomFiles)">
    <DestinationRelativePath>pages/%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
  </DotnetPublishFiles>
</ItemGroup>
Obviamente, deberíamos incluir de la misma forma otras carpetas de archivos Razor de nuestro proyecto, por ejemplo si estamos utilizando áreas, o si hemos modificado las convenciones de ubicación.
Al completar la publicación, si ejecutamos nuestro proyecto veremos que todo funciona correctamente, pero si intentamos modificar alguno de los archivos Razor incluidos en el despliegue y accedemos a él desde el navegador, obtendremos un error como el siguiente:

Error de compilación al modificar una vista en tiempo de ejecución

Este error indica que el servidor no dispone de los componentes necesarios para compilar las vistas, veamos cómo solucionarlo.

2. Hacer que las vistas puedan ser compiladas al vuelo

De nuevo, la forma de solucionarlo va a ser muy sencilla. Basta con añadir la propiedad <CopyRefAssembliesToPublishDirectory> con el valor "true" en el archivo del proyecto:
<PropertyGroup>
  <TargetFramework>netcoreapp2.1</TargetFramework>
  <CopyRefAssembliesToPublishDirectory>true</CopyRefAssembliesToPublishDirectory>
</PropertyGroup>
Al hacerlo veremos que nuestro paquete de publicación crece considerablemente (en una aplicación casi vacía con la que estoy probando, pasa de 6 a 33MB), pero ya se estarán incluyendo todos esos componentes que faltaban para hacer la compilación posible.

¡Y esto es todo! Espero que el truco os resulte útil para aplicarlo en vuestros proyectos.

Publicado en Variable not found.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

Aún no hay comentarios, ¡sé el primero!

Artículos relacionados: