Despliegue de aplicaciones web DotVVM y .NET Core en Azure
Tags: webdev, azure, dotnet, dotvvm
Published: 2020-03-10 15:41:31

####Despliegue continuo de aplicaciones####

Al hablar de implementación continua hacemos referencia a la siguiente definición:

“La entrega continua es la habilidad de llevar cambios nuevos de cualquier tipo (características, configuraciones, correcciones, y experimentos) a producción o a las manos del usuario, sin peligro y rápidamente”. Jez Humble.

Esta definición nos quiere decir que tenemos diversas ventajas al hacer uso de implementación continua, entre estas:

+ Automatización del proceso de publicación de software.
+ Mejorar la productividad de desarrollo.
+ Encontrar y arreglar los errores con mayor rapidez.
+ Entregar las actualizaciones a los usuarios con mayor rapidez.

Para aplicar estos conceptos, realizaremos el proceso de dos maneras: la primera a través de un despliegue directo de una aplicación web con DotVVM y .NET Core desde Visual Studio 2019; y como segunda manera, asociar el mismo proyecto a un repositorio en GitHub y con ese repositorio realizar implementación continua hacia Azure App Service. 

Al finalizar, analizaremos varios aspectos importantes, entre estos: la base de datos asociada al proyecto, la implementación continua con .NET Core 3.X, proyectos DotVVM con Business Pack y los errores de compilación que se puedan presentar con aplicaciones web desarrolladas con DotVVM. 

##El entorno de la solución DotVVM##

Generalmente, una solución para la creación de aplicaciones web con .NET Core y DotVVM contiene los siguientes proyectos:

+ **DAL (Data Access Layer)**: para manejar la conexión y el acceso a la base de datos.
+ **BL (Business Layer)**: para el manejo de los servicios y la lógica del dominio de la aplicación.
+ **APP - Capa de presentación de la aplicación**. En esta sección es donde tenemos los Views y Viewmodels para el diseño de las páginas web con DotVVM.

La solución en Visual Studio 2019 tiene el siguiente aspecto: 

![](https://dev-to-uploads.s3.amazonaws.com/i/m1qeo1l6pr50v88nhdw8.png)

¿Deseas saber cuáles son los pasos para crear una aplicación DotVVM? Para ello puedes revisar este articulo: [Pasos para crear una aplicación MVVM (Model-View-Viewmodel) con DotVVM y ASP.NET Core](https://medium.com/@esdanielgomez/pasos-a-seguir-para-crear-una-aplicaci%C3%B3n-mvvm-modelo-vista-vista-modelo-con-dotvvm-y-asp-net-core-41afd67125b1).

##Implementación directa de la aplicación DotVVM a Azure desde Visual Studio 2019##

Para realizar la implementación directa desde Visual Studio hacia Azure, debemos situarnos en el proyecto `.APP` y en la sección de opciones seleccionar Publicar (o desde el menú principal de opciones: Compilar > Publicar):

![](https://dev-to-uploads.s3.amazonaws.com/i/jdenssw842dr8xe2t93r.png)

Posteriormente tendremos la opción de configurar el destino de publicación. Para nuestro caso, el destino de interés será seleccionar App Service para crear un nuevo perfil: 

![](https://dev-to-uploads.s3.amazonaws.com/i/px0hvda946hqe8be37x0.png)

En este apartado debemos seleccionar *Publicar*. Luego, nos aparecerá el cuadro de diálogo *Crear servicio de aplicaciones*. Aquí debemos iniciar sesión con una cuenta de Azure, en caso de ser necesario; y después proporcionar la información necesaria para crear el recurso App Service en Azure.

![](https://dev-to-uploads.s3.amazonaws.com/i/fayyygihwge53qc0nzul.png)

En este proceso de creación de un recurso App Service, Visual Studio nos proporciona la funcionalidad para crear otros servicios de Azure para el manejo de la información de nuestra aplicación. Por ejemplo, para este caso, nos permite crear una base de datos Azure SQL Database para el posterior manejo de la información en la nube. 

![](https://dev-to-uploads.s3.amazonaws.com/i/9et5yp5whnlou4xvbz38.png)

Finalmente, luego de crear el recurso con estos pasos, Visual Studio implementará la aplicación en Azure App Service y la aplicación web se cargará en el explorador. El panel de propiedades del proyecto Publicar muestra la dirección URL del sitio y otros detalles.

![](https://dev-to-uploads.s3.amazonaws.com/i/bhj0ziihlq9t6zpu7zq5.png)

![](https://dev-to-uploads.s3.amazonaws.com/i/hmn9znfx0ih77qou6g02.png)

Después de este proceso, el resultado de despliegue directo entre Visual Studio 2019 y Azure es el siguiente:

![](https://dev-to-uploads.s3.amazonaws.com/i/cdoakftht5q6yl28v6m0.png)

##Implementación continua de la aplicación DotVVM desde GitHub a Azure##

Para la implementación continua de nuestro proyecto tenemos dos pequeños pasos por realizar: 

1. Asociar nuestro proyecto a un repositorio en GitHub. 
2. Asociar el repositorio de GitHub a Azure App Service para la implementación continua. 

####Parte 1: Asociar el proyecto a GitHub####

Lo primero que debemos hacer es verificar que tengamos instalada la extensión de GitHub para Visual Studio 2019. En cualquier caso, la extensión la podemos descargar en la siguiente dirección: [GitHub Extension for Visual Studio](https://visualstudio.github.com/).

Para agregar la extensión, Visual Studio debe estar cerrado para poder instalar GitHub ya que son cambios al IDE de Microsoft que se realizan durante la instalación. 

Ahora sí, dicho esto, procedemos a asociar a la solución que contiene los tres proyectos (`.APP`, `.BL` y `.DAL`) a un repositorio en GitHub, para ello damos clic derecho en la solución en Visual Studio y seleccionamos agregar solución al control de código fuente:

![](https://dev-to-uploads.s3.amazonaws.com/i/ulgrmbpj4eg0axj8e6i7.jpg)

Posteriormente nos dirigimos a la vista *Team Explorer* y luego a la sección de *Sincronización*:

![](https://dev-to-uploads.s3.amazonaws.com/i/yhe6o0hbv26llox2cm8z.jpg)

Y luego seleccionamos Publicar en GitHub y continuamos con las instrucciones presentadas para la creación de un nuevo repositorio. 

![](https://dev-to-uploads.s3.amazonaws.com/i/f1e2ht5heg73m8tg281u.png)

Poco tiempo después, nuestro proyecto estará asociado al repositorio que acabamos de crear. Esto lo podemos comprobar directamente desde GitHub:

![](https://dev-to-uploads.s3.amazonaws.com/i/grfxflstljvcx3vieog4.png)

Nota: Siempre que necesitemos guardar los cambios realizados, podemos guardarlos desde la sección Cambios en Team Explorer:

![](https://dev-to-uploads.s3.amazonaws.com/i/40utdu2n04q0chciqkj9.jpg)

Y en la sección Sincronizar es necesario confirmar los cambios de salida:

![](https://dev-to-uploads.s3.amazonaws.com/i/guyo4qzst9e5luy7ht3a.jpg)

Con estos primeros pasos, nuestra aplicación DotVVM en Visual Studio 2019 ya se encuentra asociada a un repositorio en GitHub determinado. 

####Parte 2: Asociar Azure App Service con el repositorio GitHub####

En este punto, es necesario tener un servicio App Service en Azure, para ello podemos crearlo desde el portal de Azure en caso de que no tengamos una aplicación establecida o si seguimos la Parte 1 de este artículo, se puede utilizar el recurso de App Service creado anteriormente. 

Dicho esto, nuestra primera tarea será dirigirnos al recurso App Service en el portal de Azure. En la página de la aplicación, debemos seleccionar la opción Deployment Center (Centro de implementación) ubicada en el menú de la izquierda.

![](https://dev-to-uploads.s3.amazonaws.com/i/ocufpz6g26pdk4k23x2r.jpg)

En la página del centro de implementación, seleccionamos GitHub y, a continuación, iniciamos sesión y seleccionamos en *Authorize* (Autorizar).

![](https://dev-to-uploads.s3.amazonaws.com/i/0lhqy6u3mtyruuwpqrmd.jpg)

En cuanto a GitHub, en la página para compilar el proveedor, seleccionar *App Service build service* (Servicio de compilación de App Service) y, a continuación, *Continue* (Continuar). 

Luego en la página de configuración:

Desplegamos el menú y seleccionamos la organización, el repositorio y la rama que se desea implementar continuamente.

![](https://dev-to-uploads.s3.amazonaws.com/i/3pa78h4x61kybhaezmjw.png)

Después de configurar el proveedor de compilación, debemos revisar la configuración en la página de resumen y seleccionar *Finish* (Finalizar).

![](https://dev-to-uploads.s3.amazonaws.com/i/t482gibg4jub40cfe6t0.jpg)

A partir de ahora las nuevas confirmaciones del repositorio y la rama seleccionada se implementa continuamente en la aplicación alojada en App Service. En la página del centro de implementación también se puede realizar el seguimiento de las confirmaciones y las implementaciones realizadas. 

![](https://dev-to-uploads.s3.amazonaws.com/i/s7wl7fedim2kr8n4iut4.jpg)

##Casos particulares##

Hasta este punto hemos aprendido de forma general como alojar aplicaciones DotVVM de forma directa desde Visual Studio 2019 o de forma continua a través de un repositorio en GitHub. A continuación, veremos algunos casos muy particulares sobre errores que pueden suceder en el camino, configuraciones en particular y también sobre las versiones de .NET Core para aplicaciones DotVVM. 

####Deshabilitar la implementación continua entre GitHub y Azure####

Para deshabilitar la implementación continua, debemos seleccionar Disconnect (Desconectar) en la parte superior de la página Deployment Center (Centro de implementación) del recurso App Service de la aplicación.

![](https://dev-to-uploads.s3.amazonaws.com/i/dap7qef8pdrn7239qfyf.png)

Para continuar con la implementación continua en el futuro, debemos repetir el proceso de asociación al repositorio de GitHub desde la página Deployment Center (Centro de implementación) de la aplicación.

####Otras fuentes de repositorios####

Adicional a GitHub, con Azure Web App también podemos realizar implementación continua desde las siguientes fuentes: 

+ Bitbucket
+ Local Git
+ OneDrive	
+ Dropbox
+ External
+ FTP

####¿Qué ocurre con la aplicación durante la publicación en Azure?####

Todos los métodos de implementación por Azure Web App realizan cambios en los archivos de la carpeta `/home/site/wwwroot` de la aplicación en Azure. Estos archivos son los mismos que se ejecutan en producción. En este sentido, existen casos particulares en los cuales se pueden producir errores de implementación de la aplicación DotVVM en Azure. A continuación, veremos algunos errores comunes y como adquirir más información sobre estos errores. 

####Detectar errores de la aplicación web en producción en Azure####

En muchas ocasiones cuando trabajamos con el desarrollo de aplicaciones web en línea nos podemos encontrar errores como este: 

![](https://dev-to-uploads.s3.amazonaws.com/i/83jpivobnudnp0kfk4sn.png)

Este error en particular, `500 - Internal Server Error`, es un código de estado HTTP muy general que significa que algo ha salido mal en el servidor del sitio web (en este caso, Azure), pero el servidor no puede ser más específico sobre cuál es el problema exacto.

Para este caso, lo primero que podemos revisar es el Log de Errores dentro de Azure App Service. Para obtener los detalles de este log, es necesario dirigirnos al archivo `web.config` y realizar una modificación. 

Nota: Para acceder a los archivos y directorios en el recurso de Azure App Service, podemos utilizar la opción Herramientas Avanzadas en el menú del recurso desde el portal de Azure para acceder al archivo `web.config` ubicado en la ruta `D:\home\site\wwwroot>`. En las siguientes dos imágenes podemos ver esta secuencia: 

En el recurso desde el portal de Azure: 

![](https://dev-to-uploads.s3.amazonaws.com/i/utzm59x2357csrgxfeje.png)

Desde Kudu: 

![](https://dev-to-uploads.s3.amazonaws.com/i/q7o15hdgn11pfslw0tsv.png)

Una vez localizado este archivo, debemos modificar en la siguiente instrucción el parámetro `stdoutLogEnabled` con el valor `true`, el cual, permitirá generar un archivo log, en donde se puedan evidenciar los errores generados en la ejecución de la página web en producción. El archivo se encontrará en la dirección especificada en el atributo: `stdoutLogFile`. 

```csharp
<aspNetCore processPath="dotnet" arguments=".\EXE.dll" stdoutLogEnabled="true" stdoutLogFile="\\?\%home%\LogFiles\stdout" /> 
```

Al realizar los cambios tendremos algo como esto: 

![](https://dev-to-uploads.s3.amazonaws.com/i/s48kywudh7rvi83sclgj.png)

Al guardar el archivo `web.config`, cargar nuevamente la página web y encontrarnos con el error `HTTP 500 - Internal Server Error`, nos dirigimos a la dirección especificada para la generación de archivos logs, y abrimos el ultimo archivo generado: 

![](https://dev-to-uploads.s3.amazonaws.com/i/8bett9o0yb6aihmf4ll4.png)

En este caso nos encontramos con un error que dice: *A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 52 - Unable to locate a Local Database Runtime installation. Verify that SQL Server Express is properly installed and that the Local Database Runtime feature is enabled.)*

Este error es debido a un problema con la conexión de la base de datos. En este caso, intencionalmente, la conexión a la base de datos en el `.DAL` esta haciendo referencia a una base de datos local, por ende, el servidor de Azure App Service no logrará encontrar el servidor de la base de datos, generando así, este error en producción. 

Si bien es cierto, existe una gran variedad de errores que se pueden producir bajo este contexto, analizar los archivos logs, puede ahorrarnos horas de trabajo al intentar buscar el posible error que se esté presentando en la aplicación web. 

####Detectar errores en la implementación continua en Azure desde GitHub####

Azure realiza implementación continua de forma automática cuando existen cambios en el repositorio GitHub asociado, el Status final que podemos tener como resultado son dos: Success, que quiere decir que todo salió bien; o, Failed, el cual puede suceder por una gran variedad de razones. 

Al igual que el caso anterior, lo mejor que podemos hacer es revisar los logs de implementación para analizar los posibles errores que se estén presentando. Para ello, en el intento de implementación, podemos hacer clic en el icono que se muestra en la siguiente imagen para acceder a estos logs: 

![](https://dev-to-uploads.s3.amazonaws.com/i/5qaglm3ppwg8zu549ph7.png)

Para este caso en particular, en el archivo log podemos encontrar lo siguiente: 

![](https://dev-to-uploads.s3.amazonaws.com/i/7pv6nde581us9mmm1201.png)

Aquí se pudo evidenciar de forma directa el siguiente error de implementación: *The current .NET SDK does not support targeting .NET Core 3.0.  Either target .NET Core 2.2 or lower, or use a version of the .NET SDK that supports .NET Core 3.0*.

En este error en particular no hay muchas explicaciones adicionales que se puedan decir. El SDK de .NET Core aún no está disponible en la región del recurso de Azure App Service. Este caso en específico lo revisaremos en el siguiente apartado.
 
Como vemos, existe una variedad de errores que se pueden presentar durante la implementación de nuestras aplicaciones en Azure. Gracias a estos consejos podemos tener en cuenta que es lo primero que debemos hacer para detectar estos errores, que, de forma general, lo recomendable es revisar los logs de la aplicación. 

####Aplicaciones DotVVM con .NET Core 3.X####

Como vimos en el presente artículo, el estado de .NET Core 3.X en Azure es parcialmente actual. ¿Esto que significa? Esto quiere decir que el tiempo de ejecución y los marcos de trabajo están allí, pero falta el SDK de .NET 3.X. En pocas palabras, se puede ejecutar 3.X, pero no compilar 3.X. 

Ahora bien, según la página web [ASPnetCoreON](aspnetcoreon.azurewebsites.net) la cual nos permite consultar la disponibilidad de ASP.NET Core para implementar aplicaciones en Azure App Service, la disponibilidad de .NET Core según la región de Azure y la versión de .NET nos dice lo siguiente:  

![](https://dev-to-uploads.s3.amazonaws.com/i/ojthzt9bh3qdfihxchp6.png)

Existen regiones de Azure con la integración de .NET en el estado Parcialmente Actual, en el cual, se puede ejecutar .NET Core 3.X, pero no compilar .NET Core 3.X. 

Asimismo, la región West US 2 y North Central US tienen el estado es: Actual, es decir, que se pueden crear aplicaciones .NET Core 3.1 en Azure y ejecutar aplicaciones .NET Core 3.1 en esta región. (Febrero, 2020). 

Si analizamos a detalle esta información, en las dos regiones mencionadas anteriormente, nos encontramos con lo siguiente: 

![](https://dev-to-uploads.s3.amazonaws.com/i/rvu9izworke6ll6gypy1.png)

Esto quiere decir que podemos implementar de forma continua nuestras aplicaciones DotVVM desde GitHub con .NET Core 3.1, 2.2, 2.1 y con 1.1. 

Algo muy importante por mencionar, es que DotVVM desde su versión 2.4 ya nos permite trabajar con .NET Core 3.1 ([Released DotVVM 2.4](https://www.dotvvm.com/blog/66/Released-DotVVM-2-4)).

Para cambiar la versión en nuestra solución, será necesario cambiar las versiones de las plataformas destino en los proyectos `.APP`, `.BL` y `.DAL` desde Visual Studio 2019:

![](https://dev-to-uploads.s3.amazonaws.com/i/iew6buzp5c5xu06pcep7.png)

Una alternativa adicional *(Febrero, 2020)* es considerar la opción de trabajar con .NET Core 2.2, versión que hasta el momento no tiene ningún problema en ninguna de las regiones para la implementación continua de aplicaciones en Azure.

####Un error adicional####

Un error cuya solución no fue fácil de encontrar es el siguiente: 

![](https://dev-to-uploads.s3.amazonaws.com/i/doul43ch71hq9zympwn8.jpg)

Este error fue generado al momento de despliegue directo entre Visual Studio y Azure, asimismo, el error también se genera al momento de realizar implementación continua desde GitHub. 

.NET Core y DotVVM específicamente utilizan archivos estáticos para emplear estilos CCS, componentes de Javascript, imágenes, entre otros archivos, a través de la carpeta `wwwroot` (distinta a la que utiliza Azure App Service – No existe ninguna relación de nombres entre `wwwroot` de Azure y `wwwroot` de DotVVM). 

Dentro de DotVVM, en `StartUp.cs` se especifica la ruta que contendrá los archivos estáticos antes mencionados a través del método `Configure( … )` en la instrucción `app.UseStaticFiles(…)`. En caso de que la carpeta `wwwroot` se encuentre vacía (sin ningún archivo), Azure Web Service genera conflictos con esto y presenta el error de la imagen anterior. 

Para solucionar este error, la carpeta `wwwroot` en el proyecto `.APP` de DotVVM no debe estar vacía. Si bien es cierto esta respuesta desde un punto técnico no tiene mucha explicación, pero es una posible solución a esta problemática que podría ahorrar mucho tiempo (una cantidad bastante considerable de tiempo) en la búsqueda para resolver este problema. 

####Aplicaciones DotVVM con Business Pack ####

¿Tu proyecto DotVVM emplea Business Pack para el manejo de controles PRO? En este caso, la implementación a Azure no se verá afectada, ya que todos los paquetes NuGet de DotVVM Business Pack también serán implementados hacia Azure con los demás paquetes a los cuales el proyecto haga referencia.  

####Plus: conexión de la base de datos en el proyecto .DAL con Azure SQL Database ####

Para trabajar con nuestra aplicación web en la nube, es necesario que la base de datos asociada al proyecto también se encuentre en la nube, para ello, en el `DBContext` del proyecto `.DAL`, es necesario implementar el método `OnConfiguring` de la clase `DbContext`, como se muestra a continuación: 

```csharp
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{                
    optionsBuilder.UseSqlServer("Sentencia de conexión");
}
```

Esto nos permitirá establecer la conexión con la base de datos en la nube, teniendo en cuenta la relación que debe existir entre las Entidades de la base de datos y las clases en el proyecto `.DAL`. 

##Gracias!##

Con este articulo hemos aprendido todo lo que necesitamos saber (al menos la mayoría) para la implementación de aplicaciones DotVVM con .NET Core en Azure. 

¿Deseas practicar lo aprendido en este articulo? Para ello puedes ver el siguiente tutorial sobre [Operaciones CRUD en DotVVM](https://dev.to/esdanielgomez/dotvvm-y-asp-net-core-implementacion-de-operaciones-crud-43oe), acceder al código fuente y poner en práctica estos conocimientos. 

Cualquier inquietud no dudes en escribirme. 

Nos vemos en [Twitter](https://twitter.com/esDanielGomez)!! :)