La historia cuenta que la construcción de interfaces gráficas para la Web ha estado completamente dominada por Javascript, hasta ahora, pues con el surgimiento de nuevas formas de construir aplicaciones para la web, entre ellos WebAssembly, se han incorporado al portafolio de opciones nuevas herramientas.
Acá es donde aparece Blazor: La plataforma propuesta por Microsoft para la construcción de aplicaciones web usando .NET que elimina - casi - por completo la necesidad de usar Javascript.
No caeré en el clic-bait de decir que vas a construir web sin Javascript, pero si podré asegurar que en la mayoría de los entornos no encontrarás la necesidad de usarlo, salvo casos muy especiales.
Blazor es un marco web de front-end de .NET que admite la representación del lado servidor y la interactividad del cliente en un único modelo de programación:
Permite crear las interfaces de usuario con C#. mediante HTML y CSS para la compatibilidad con todos los exploradores, incluidos los móviles.
La lógica de aplicación del lado cliente y servidor escrita con .NET.
Puede usarse para aplicaciones híbridas de escritorio y móviles con .NET y Blazor.
El uso de .NET para el desarrollo web en el lado cliente ofrece las siguientes ventajas:
Escritura de código en C#, lo que puede mejorar la productividad en el desarrollo y el mantenimiento de aplicaciones.
Aprovechamiento del ecosistema .NET existente de bibliotecas .NET.
Beneficios de rendimiento, confiabilidad y seguridad de .NET.
Compile sobre un conjunto común de lenguajes, marcos y herramientas que son estables, completos y fáciles de usar.
En Blazor podrá escribir aplicaciones que se ejecuten:
Del Lado del Cliente usando WebAssembly, una tecnología que permite que el código sea cargado en el navegador (como pasa con JavaScript) y que se ejecute directamente del lado del cliente.
Del Lado del Servidor. Donde ASPNET Core compila y ejecuta el código entregando el código ya listo para ser renderizado en HTML y CSS
Con .NET tenemos una opción mucho mejor y es juntar ambos mundos y poder decidir cuándo usar una opción u otra. Por ahora usaremos lo básico de Blazor.
Creación del Proyecto
El proyecto lo crearemos usando las herramientas de Visual Studio Code, seleccionando en la barra de tareas > .NET: New Project ...
Y seleccionando Blazor WebAssembly StandAlone App
Estos nos creará un proyecto con la siguiente estructura
Veamos de que se trata cada carpeta y archivo
Layout contiene dos elementos, la plantilla MainLayout que determina la estructura general, si abres el archivo verás que tiene contenido HTML
Pages son las páginas de nuestro proyecto, donde ubicaremos el contenido que será mostrado al visitante del sitio
Properties son archivos de configuración
wwwroot carpeta donde puede ubicarse el código estático Hojas de Estilo, Imágenes, Archivos Javascript, etc
_Imports.razor archivo donde se configuran las importaciones generales del proyecto
App.razor es el componente que tiene el punto de entrada de nuestra aplicación web
Program.cs contiene todo el código de inicialización de la aplicación, la inyección de dependencias, configuración de accesos a servicios web, etc
Si te curiosidad, puedes ingresar a la carpeta BlazorWeb y lanzar este comando
dotnet watch
Este comando compila y ejecuta el proyecto y queda atento a los cambios para realizar de nuevo el proceso, veras en la salida de esa consola un texto como este Now listening on: localhost:xxxx
Da clic en esa ruta o ingresala en el navegador y tendrás ya el sitio ejecutandose
Reutilización de código
En nuestra arquitectura hemos creado un proyecto llamado Modelos, por ahora sin entrar en mayor rigor de arquitectura, este proyecto contendrá el contenido que compartiremos y es necesario agregarlo al proyecto de BlazorWeb
dotnet sln add .\BlazorWeb\
Para que el comando funcione correctamente debemos estar ubicados en la raíz de la carpeta de nuestra solución
Ahora vamos a agregar la referencia de Modelos a nuestro proyecto BlazorWeb
dotnet add .\BlazorWeb\ reference .\Modelos\
Conexión del Front al API
Este paso nos permitirá consultar y crear posteriormente estaciones de servicio y para hacerlo nuestro Blazor debe conocer la ruta del API. Preparemos el entorno para eso permitiendo que se ejecuten ambos proyectos (El WebApi y el BlazorWeb), para esto, en la carpeta .vscode, crea un archivo con el nombre tasks.json con el siguiente código
{
"version": "2.0.0",
"tasks": [
{
"label": "Compilar WebApi",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/WebApi/WebApi.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "Compilar Blazor",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/BlazorWeb/BlazorWeb.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}
Ahora crea un archivo con el nombre launch.json e ingresa el siguiente código
{
"configurations": [
{
"name": "Iniciar Blazor",
"type": "blazorwasm",
"request": "launch",
"preLaunchTask": "Compilar Blazor",
"program": "${workspaceFolder}/BlazorWeb/bin/Debug/net8.0/BlazorWeb.dll",
"cwd": "${workspaceFolder}/BlazorWeb",
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
{
"name": "Iniciar Web Api",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Compilar WebApi",
"program": "${workspaceFolder}/WebApi/bin/Debug/net8.0/WebApi.dll",
"args": [],
"cwd": "${workspaceFolder}/WebApi",
"stopAtEntry": false,
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
}
],
"compounds": [
{
"name": "Iniciar Solución",
"configurations": [
"Iniciar Web Api",
"Iniciar Blazor"
],
"stopAll": true
}
]
}
Una vez guardes ambos archivos, presiona F5 y verás que se lanzan dos navegadores, cada uno con un proyecto diferente.
Ahora, para conectar nuestro WebApi proyecto BlazorWeb modifica el archivo, como se indica
Program.cs
//Cambia esta linea, se documenta porque ya no es necesaria
//builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("builder.HostEnvironment.BaseAddress") });
//Por esta linea
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("https://localhost:7140/") });
La línea que se agrega toma la URL del WebApi, al ejecutar el proyecto con F5 verás que se inician dos navegadores, toma la URL del navegador donde se ejecuta el WebAPI ¿lo encuentras? Déjame saber si existe algún problema.
Ahora debemos agregar un nuevo componente razor al proyecto, crea en la carpeta Pages y archivo llamado Estaciones.razor
@page "/estaciones"
@using Modelos
@inject HttpClient Http
<h3>Estaciones</h3>
@if (estaciones == null)
{
<p><em>Cargando...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Dirección</th>
<th>¿Esta Abierta?</th>
</tr>
</thead>
<tbody>
@foreach (var estacion in estaciones)
{
<tr>
<td>@estacion.EstacionDeServicioId</td>
<td>@estacion.Direccion</td>
<td>@estacion.EstaAbierta</td>
</tr>
}
</tbody>
</table>
}
@code {
private EstacionDeServicio[]? estaciones;
protected override async Task OnInitializedAsync()
{
estaciones = await Http.GetFromJsonAsync<EstacionDeServicio[]>("/estaciones");
}
}
Este código es una mezcla de HTML y .NET, permitiendo interactuar con código C# en las diferentes vistas.
Este proyecto va a cambiar con el tiempo, buscaremos integrar mapas para ver las estaciones de servicio más cercana, reportar los precios de manera colaborativa, etc.
Por ahora mi interés principal es que llegues hasta acá con el proyecto funcionando, ¿como vamos?
Déjame saber si existe alguna duda y preparémonos para integrar un App Móvil.