Hoy va un post cortito, pero que puede venir bien a alguien que esté intentando "trocear" su aplicación en distintos proyectos y se haya encontrado con este problema.
Echemos un vistazo al contenido típico del archivo App.razor
de una aplicación Blazor (Server o WebAssembly, da lo mismo):
<Router AppAssembly="@typeof(Program).Assembly">
...
</Router>
Resulta que el componente Router
escanea durante su inicialización el ensamblado que hayamos indicado en su atributo AppAssembly
, por defecto el ensamblado actual, en busca de componentes que:
- Hayan definido sus rutas mediante directivas
@page
de Razor, - o bien, que tengan su ruta especificada con atributos
[Route]
En cualquiera de los casos, los componentes localizados son añadidos a la tabla de rutas y, por tanto, será posible navegar hacia ellos modificando la ruta del navegador, ya sea programáticamente (usando el servicio NavigationManager
) o bien mediante la pulsación de enlaces o modificación directa en la barra de direcciones.
Hasta aquí, todo correcto. El problema viene cuando las páginas que queremos añadir a la tabla de rutas no están en el ensamblado actual, o se encuentran repartidas en varios ensamblados distintos, por ejemplo en:
- Otros proyectos de la solución
- Ensamblados externos, referenciados directamente
- Paquetes NuGet instalados en el proyecto
Publicado por José M. Aguilar a las 8:05 a. m.
Etiquetas: blazor, blazorserver, blazorwasm
Creo que nunca me he topado en persona con este código de error, así que es una buena ocasión para conocer un poco sobre él.
El código HTTP 505 (HTTP Version Not Supported) es retornado por un servidor cuando rechaza o no soporta la versión major de HTTP utilizada en la petición. En este caso, se recomienda que el servidor incluya en la respuesta la descripción del motivo por el que no soporta la versión utilizada, y qué protocolos debería usar en su lugar.
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Cómo invocar métodos estáticos C# desde Javascript con Blazor (interop 2/3)
José María Aguilar - Imágenes en cuadros de texto de formularios web
José María Aguilar
.NET Core / .NET
- Null-Coalescing ?? And Null-Coalescing Assignment ??= Operator
Code Maze - Enforcing .NET code style rules at compile time
Daniel Genezini - The Best C# 11 Feature You Don't Need
Matt Eland - My C# array, tuple, delegate declaration dilemma
Jiří Činčura - How to Return null From a Generic Method in C#
Code Maze - Introducing the C# 11 Required Keyword
Matt Eland - My favourite 'recent' LINQ improvements
Mark Heath - How to Use the “Using Static” Feature in C#
Code Maze - Book: C# for Babies
JetBrains - Using Dynamic LINQ With System.Linq.Dynamic.Core Library
Code Maze - C# 11 and .NET 7 Bring Generic Parsing
Jonathan Allen - C# 11 required members
Patrick Smacchia - Protect yourself when deserializing - System.Text.Json
Josef Ottosson - Anonymous test data with AutoFixture
Steven Giesel - Cysharp/MemoryPack: Zero encoding extreme performance binary serializer for C# and Unity.
Yoshifumi Kawai
La llegada de C#11 viene acompañada de un buen número de novedades, algunas de ellas bastante jugosas, como los raw string literals o el nuevo modificador "file" que ya hemos ido viendo por aquí.
En esta ocasión, vamos a echar el vistazo a otra de las novedades que pueden resultar de bastante utilidad en nuestro día a día: los miembros requeridos.
Como vimos hace unas semanas, el código HTTP 502 es usado por gateways, proxies o intermediarios similares para informar al cliente de que la petición al servidor real estaba retornando un error, pero, ¿qué ocurre cuando dicho servidor ni siquiera responde en un tiempo determinado? Pues para eso existe el HTTP 504 (Gateway timeout).
Y ahora, ahí van los enlaces recopilados durante la semana pasada, con muchas novedades y lanzamientos que, como de costumbre, espero que os resulten interesantes. :-)
Por si te lo perdiste...
- ¿A qué huele tu código?
José María Aguilar - Cómo invocar funciones Javascript desde Blazor (interop)
José María Aguilar
.NET Core / .NET
- .NET 7 is Available Today
Jon Douglas - Welcome to C# 11
Mads Torgersen - Announcing F# 7
Vlad Zarytovskii - Announcing NuGet 6.4 - Signed, Central, Delivered
Jon Douglas - What's new in Windows Forms in .NET 7.0
Igor Velikorossov - What's new for WPF in .NET 7
Pankaj Chaurasia - What's new in Orleans 7.0
Brady Gaster - Mutable value types are evil! Sort of...
Steven Giesel - Top 10 Dotnet Exception Anti-Patterns in C#
Matt Eland - How to Use HTML Agility Pack in C#
Diego García - Debugging tips and tools
Gérald Barré - Tasks vs Threads in C#
Code Maze - Concurrent Processing in .NET 6 with System.Threading.Channels (Bonus: Interval Trees)
Charles Chen - Source Generated RegEx in .NET 7
Steve Collins
En código que veo, incluso escrito por mí un tiempo atrás, es muy habitual encontrar comparaciones de cadenas de caracteres en las que, para asegurar que el casing no sea tenido en cuenta, se fuerza una conversión de alguno de los operandos, o incluso ambos, a mayúsculas o minúsculas.
En escenarios muy simples esto funcionará bien y no tendrá contraindicaciones especialmente graves para nuestro sistema. Veamos unos ejemplos:
// Ejemplo 1: conversión de un único operando
int Calculate(string op, int a, int b)
{
// Pasamos a minúsculas el operador para
// asegurar que encaja con la constante
if(op.ToLower()=="add")
{
return a+b;
}
else if(op.ToLower()=="sub")
{
return a-b;
}
...
}
// Ejemplo 2: conversión de ambos operandos
bool AreBrothers(User user1, User user2)
{
// Pasamos a mayúsculas ambos apellidos por
// si alguno se ha escrito usando otro casing
var areBrothers = user1.Surname.ToUpper() == user2.Surname.ToUpper();
return areBrothers;
}
Sin embargo, aunque pueda parecer despreciable, estas operaciones de transformación a mayúsculas o minúsculas tienen un coste importante, que se pone especialmente de manifiesto cuando estamos hablando de aplicaciones con mucha carga de usuarios, alojada en infraestructura muy ajustada o cuando se requiere un rendimiento extremo.
El error HTTP 503 (Service unavailable) lo retornan los servidores para indicar que no están disponibles para responder a la petición. Es habitual encontrarlo al intentar acceder a un sitio web que está en mantenimiento, temporalmente fuera de servicio, o ante un estado de sobrecarga (alta concurrencia, bajos recursos, etc.) El cliente debe interpretarlo como un error temporal, y puede volver a intentarlo de nuevo algo más adelante; para ello, a veces suele acompañarse de un encabezado Retry-After
con la fecha/hora o el número de segundos estimados en los que volverá a estar operativo.
Y ahora, ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Cómo mostrar y ocultar elementos en Blazor
José María Aguilar - 8 curiosidades que quizás no conocías sobre los emoticonos ;-), Parte 1 y Parte 2
José María Aguilar
.NET Core / .NET
- Announcing .NET Community Toolkit v8.1.0 Preview 1
Sergio Pedri - Local functions vs lambda expressions
Steven Giesel - Handling times for an EV charger
Jon Skeet - Deserializing Json Streams using Newtonsoft.Json & System.Text.Json with C# & VB
Graeme_Grant - Advanced LINQ
Alvaro Montoya - Injectio - Source Generator for Dependency Injection
Paul Welter - Encrypt and Decrypt Text Values in .NET
Jamil Hallal - Getting Started With Worker Services
Assis Zang - Just store UTC? Not so fast! Handling Time zones is complicated.
Derek Comartin - Bring WCF apps to the latest .NET with CoreWCF and Upgrade Assistant
Sam Spencer - Marking API's as obsolete or as experimental
Steven Giesel