Saltar al contenido

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

17 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 Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 19 de marzo de 2024
Blazor

Como sabéis, con ASP.NET Core 8 se ha incluido la posibilidad de que una página Blazor sea capaz de procesar directamente una petición HTTP, renderizando sus componentes y retornando el resultado HTML completo al lado cliente de forma estática. Es ya lo vimos hace algún tiempo cuando hablamos de Server-Side Rendering (SSR), una de las piezas clave para conseguir que Blazor sea un framework fullstack.

En la práctica, esta opción posibilita la implementación de sitios estáticos completos, como los que construiríamos con ASP.NET Core MVC, Razor Pages o cualquier otro tipo de tecnología de servidor, pero con la gran ventaja de que en este caso estaremos beneficiándonos del fantástico modelo de componentes Blazor, que es una gozada en términos de productividad y facilidad de uso, y sin perder la posibilidad de activar la interactividad de los componentes (su capacidad para reaccionar ante eventos del usuario), una vez que el HTML ha sido descargado en el navegador.

En aquél momento vimos que SSR no requiere una programación específica: los mismos componentes interactivos que luego podemos ejecutar en el lado cliente o servidor pueden ser renderizados mediante SSR de forma estática en el backend. Sin embargo, en algunos momentos nos podría resultar interesante saber si un componente está funcionando en modo estático (SSR) o interactivo (los tradicionales Blazor WebAssembly o Blazor Server).

En principio, no hay una forma "oficial" de saberlo. Sin embargo, podríamos detectarlo de forma sencilla basándonos en algo que vimos poco tiempo atrás: cuando se está procesando una petición mediante SSR, el framework introduce automáticamente como parámetro en cascada un objeto de tipo HttpContext con toda la información relativa a la petición actual.

Por tanto, si un componente recibe un parámetro en cascada de tipo HttpContext, podemos estar seguros de que se está ejecutando en modo SSR, mientras que si no lo recibe, es que se está ejecutando de forma interactiva. De esta forma, podemos definir un parámetro en cascada de este tipo en el componente, y comprobar si es null o no, como vemos a continuación:

@page "/test"
@if(HttpContext is null) 
{
    <p>Este componente se está ejecutando en modo interactivo</p>
}
else 
{
    <p>Este componente se está ejecutando en modo SSR</p>
}

@code {
    [CascadingParameter]
    private HttpContext? HttpContext { get; set; }
}

Sin embargo, como también vimos en el post anterior, esta solución no es correcta del todo, porque sólo deberíamos acceder a HttpContext desde en el componente raíz de la aplicación (normalmente App.razor). Aunque funcionará bien en componentes definidos en el proyecto principal de una Aplicación Web Blazor, que son ejecutados siempre en el servidor, no funcionaría en componentes definidos en el proyecto que se ejecuta en el lado cliente, <MyProject>.Client; de hecho, ni siquiera compilaría, porque la clase HttpContext es una abstracción de servidor y no existe en el lado cliente.

Si queremos dar una solución más general, válida para componentes definidos en servidor y en cliente, tendríamos que determinar si estamos en modo SSR desde el componente raíz, y luego hacer llegar esa información a todos los componentes descendientes en la jerarquía.

Este podría ser el código en el componente raíz. Como podemos ver, hacemos que el componente <CascadingValue> rodee a <Routes>, de forma que todas las páginas y sus componentes descendientes podrán recibir el valor de IsSSR, obtenido a partir de la existencia o no de HttpContext:

...
<body>
    <CascadingValue IsFixed="true" Name="IsSSR" Value="IsSSR">
        <Routes />
    </CascadingValue>
    <script src="_framework/blazor.web.js"></script>
</body>
...
@code
{
    [CascadingParameter]
    public HttpContext? HttpContext { get; set; }

    private bool IsSSR => HttpContext is not null;
}

Y más adelante, en el componente que queramos detectar si se está ejecutando en modo SSR o interactivo, podríamos hacer lo siguiente:

@page "/mypage"
...
@if(IsSSR)
{
    <p>Este componente se está ejecutando en modo SSR</p>
}
else
{
    <p>Este componente se está ejecutando en modo interactivo</p>
}

@code {
    [CascadingParameter(Name = "IsSSR")]
    private bool IsSSR { get; set; }
}

Espero que os sea de utilidad :)

Publicado en Variable not found.

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