La sintaxis Razor permite combinar marcado HTML con expresiones y bloques de código C# dentro de un mismo archivo.
Si vienes de otros frameworks, quizá estés acostumbrado a expresiones como {{ variable }} o a directivas como ng-repeat. En Blazor usamos C# para la lógica de los componentes, junto con HTML, CSS y, cuando hace falta, JavaScript.
Razor no es un nuevo lenguaje de programación; es una sintaxis de marcado que permite incrustar código basado en servidor (C#) en páginas web.
Lo genial de Razor es que tiene una “inteligencia” para detectar transiciones. Sabe cuándo estás escribiendo HTML y cuándo has cambiado a C#, sin necesidad de cerrar etiquetas constantemente.
El símbolo especial: @
En Razor, el carácter @ es el protagonista absoluto. Es el encargado de decirle al compilador: “Oye, lo que viene a continuación es código C#, no texto”.
Expresiones implícitas
Es la forma más común. Simplemente ponemos @ seguido de una variable o propiedad.
<h3>Hola, @NombreUsuario</h3>
<p>Hoy es: @DateTime.Now</p>Razor es lo suficientemente listo para saber que NombreUsuario es una variable y que cuando termina (por ejemplo, al encontrar un espacio o una etiqueta HTML), debe volver a interpretar el código como HTML.
Expresiones explícitas
A veces, Razor se confunde. Por ejemplo, si quieres realizar una operación matemática simple o concatenar texto sin espacios. En esos casos, usamos paréntesis @( ... ) para delimitar claramente el código C#.
<p>Total: @Precio€</p>
<p>Total: @(Precio)€</p>
<p>El doble de tu edad es: @(Edad * 2)</p>Usa expresiones explícitas @(...) cuando hagas cálculos, llames a métodos genéricos o necesites delimitar con claridad dónde termina el código.
Bloques de código @{ ... }
A veces no nos basta con imprimir una variable; necesitamos ejecutar lógica (declarar variables locales, realizar cálculos complejos) antes de pintar el HTML. Para eso usamos los bloques de código.
@{
var mensaje = "Bienvenido al curso";
var esFinDeSemana = DateTime.Now.DayOfWeek == DayOfWeek.Sunday;
if(esFinDeSemana)
{
mensaje += " ¡Feliz Domingo!";
}
}
<div class="alert alert-info">
@mensaje
</div>Es importante entender el alcance (scope): Las variables definidas dentro de un bloque @{ ... } solo existen dentro del método de renderizado de ese momento. No son propiedades de la clase (para eso usamos el bloque @code, que veremos luego).
Estructuras de control
Razor resulta especialmente útil con las estructuras de control de flujo de C# (if, switch, foreach), que podemos mezclar directamente con HTML.
Con un condicional decides si un elemento se incluye o no en el árbol de renderizado. No es lo mismo que ocultarlo mediante CSS, porque en este caso el elemento no se genera.
@if (IsLoading)
{
<p>Cargando datos...</p>
}
else
{
<p>Los datos están listos.</p>
}Generar listas o tablas es trivial. Iteramos sobre una colección de C# y pintamos HTML en cada vuelta.
<ul>
@foreach (var producto in ListaProductos)
{
<li>
<strong>@producto.Nombre</strong> - @producto.Precio €
</li>
}
</ul>Fíjate en la transición: empezamos con C# (foreach), abrimos una llave { y, al escribir la etiqueta <li>, Razor entiende que volvemos a HTML. Cuando encuentra @producto, cambia de nuevo al contexto de C#.
Atributos dinámicos
También podemos usar C# para controlar los atributos de las etiquetas HTML, como clases, IDs, o estados de inputs.
<input type="checkbox" checked="@EstaActivo" />
<div class="@(EsError ? "bg-red-500" : "bg-green-500")">
Mensaje de estado
</div>Si el valor de la expresión es null o false (en atributos booleanos), Razor es inteligente y elimina el atributo completamente del HTML renderizado, manteniendo el DOM limpio.
Directivas básicas
Las directivas son comandos especiales que cambian la forma en que se compila o se comporta el componente. Empiezan por @ pero suelen ser palabras reservadas.
- @page: Define la ruta URL del componente.
@page "/mi-perfil"- @code: El bloque más importante. Aquí definimos la lógica de la clase del componente (propiedades, métodos, eventos).
@code {
private string Titulo = "Mi Web";
private void Saludar() { ... }
}- @using: Igual que en C# estándar, importa espacios de nombres para no tener que escribir
System.Collections.Generic.List.... - @inject: Se usa para la Inyección de Dependencias (lo veremos a fondo en su propio artículo).
Un ejemplo completo
Vamos a juntar todo lo visto en un componente que simula una lista de tareas.
@page "/tareas"
<h3>Mis Tareas (@Tareas.Count)</h3>
@if (Tareas.Count == 0)
{
<div class="alert alert-warning">No tienes tareas pendientes. ¡A descansar!</div>
}
else
{
<ul class="list-group">
@foreach (var tarea in Tareas)
{
<li class="list-group-item @(tarea.Completada ? "list-group-item-success" : "")">
<input type="checkbox" checked="@tarea.Completada" />
@(tarea.Completada ? "✅" : "⏳") @tarea.Descripcion
</li>
}
</ul>
}
@code {
// Definición de una clase simple dentro del mismo archivo para el ejemplo
public class Tarea
{
public string Descripcion { get; set; }
public bool Completada { get; set; }
}
// Lista de datos
private List<Tarea> Tareas = new List<Tarea>
{
new Tarea { Descripcion = "Aprender Razor", Completada = true },
new Tarea { Descripcion = "Dominar Blazor", Completada = false },
new Tarea { Descripcion = "Escribir código limpio", Completada = false }
};
}Cómo escapar un @ literal
¿Qué ocurre si quieres mostrar un texto que comienza por @, como un nombre de usuario?
Las direcciones de correo completas dentro del contenido o de un atributo se reconocen normalmente como texto. Para escribir un @ literal en otros casos, debes escaparlo duplicándolo:
Para solucionar esto, debemos escapar el símbolo @ duplicándolo:
<p>Sígueme como @@LuisLlamasEs</p>El navegador mostrará @LuisLlamasEs.