Error 404 cargando páginas Blazor Server con parámetros que contienen un punto - Code Variables -->
Code Variables Code Variables

Latest news

جاري التحميل ...

Error 404 cargando páginas Blazor Server con parámetros que contienen un punto

Blazor

Un alumno del curso de Blazor que tutorizo en CampusMVP me exponía problema bastante curioso con el que se había topado al implementar una página que, simplificando el escenario, venía a ser como la siguiente:

@page "/sum/{a:decimal}/{b:decimal}"

<h1>The sum is: @(A+B)</h1>

@code {
[Parameter] public decimal A { get; set; }
[Parameter] public decimal B { get; set; }
}

Esta página funcionaba correctamente con números enteros: podíamos acceder a "/sum/1/2" y veíamos el resultado correcto ("The sum is: 3"). Esto era así tanto accediendo a través del sistema de routing de Blazor (es decir, usando un link hacia esa ruta desde dentro de la aplicación) como accediendo directamente a la página introduciendo la ruta en la barra de direcciones del navegador.

Sin embargo, el problema surgía al usar valores decimales. Si desde dentro de la aplicación pulsábamos un enlace hacia "/sum/1.1/2.2", el resultado obtenido era correcto ("The sum is: 3.3"). Sin embargo, si en ese momento refrescábamos esa página, o bien accedíamos directamente a ella introduciendo la URL en el navegador, el servidor retornaba un error 404.

Extraño, ¿no?

Acotando el problema

Tras reproducir el escenario, vi claro que el problema no estaba en el sistema de routing de Blazor, pues los accesos a la página usando links funcionaban correctamente.

El error 404 lo estaba retornando el servidor cuando cargábamos la página por completo, es decir, refrescando o accediendo directamente a la URL con el navegador. Como consecuencia, el origen no estaba en Blazor sino más abajo, en ASP.NET Core.

Y aunque podría parecer lo contrario en un principio, el tema no tenía que ver con decimales o algo parecido, sino con la propia ruta que estamos usando en la petición. Es decir, el problema era exactamente el mismo con el siguiente componente si hacíamos una petición a "/hello/john.smith":

@page "/hello/{name}"

<h1>Hello: @Name</h1>
@code {
[Parameter] public string Name { get; set;}
}

Es decir, este comportamiento ocurre cuando el último fragmento de la ruta de acceso a la página contiene un punto ".", como en "1.3" o "john.smith".

Esto podemos comprobarlo si añadimos a la ruta cualquier fragmento adicional, de forma que el valor con punto no sea el último fragmento, como en el siguiente ejemplo; en este caso, peticiones como "/john.smith/hello" funcionará sin problemas:

@page "/{name}/hello"

¿Por qué ocurre esto? Y sobre todo, ¿cómo lo solucionamos?

Pues básicamente porque si la ruta de acceso termina por un fragmento que contiene un punto, el framework piensa que se trata de una petición a un archivo estático, y, según la configuración por defecto, no ejecuta el fallback hacia _Host.cshtml.

El culpable se encuentra en la llamada a MapFallbackToPage() que encontramos en el método Configure() de la clase Startup:

app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});

En principio, esa línea mapearía un fallback para que cualquier ruta que no haya sido configurada en otro endpoint sea procesada por la página Pages/_Host.cshtml. El problema es que internamente esa línea equivale a la siguiente:

endpoints.MapFallbackToPage("{*path:nonfile}", "/_Host");

Como se puede ver, el fallback mapea una ruta catch-all para asociarla a la página _Host, pero le añade la restricción nonfile, lo que indica que no se tendrán en cuenta peticiones que aparentemente vayan dirigidas a un recurso estático.

De esta forma, cualquiera de las peticiones que hacíamos más arriba, como "/sum/1.1/2.2" o "/hello/john.smith" no superaban la restricción y, por tanto, no se hacía el fallback hacia la página host de la aplicación Blazor. Además, dado que no existía otro endpoint para dichas URLs, la única opción para el sistema era retornar un 404, indicando que el recurso no había podido ser localizado.

Para solucionarlo, simplemente debemos sustituir el mapeo del fallback, eliminando la restricción nonfile de la siguiente forma:

app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
// endpoints.MapFallbackToPage("/_Host");
endpoints.MapFallbackToPage("{*path}", "/_Host");
});

¡Espero que os sea de ayuda!

Publicado en Variable not found.

Comments



If you like the content of our blog, we hope to stay in constant communication, just enter your email to subscribe to the blog's express mail to receive new blog updates, and you can send a message by clicking on the button next ...

إتصل بنا

About the site

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

Learn more ←

Blog visitors

Blog stats

All Copyrights Reserved

Code Variables

2019