lunes, 25 de mayo de 2020
El código de estado HTTP 405 es utilizado por los servidores para indicar a los clientes que el recurso solicitado existe, pero el método empleado para tener acceso al mismo no es correcto. Esto podemos verlo si, por ejemplo, hacemos una petición de tipo POST a un endpoint que sólo soporta PUT, o cualquier otra combinación incorrecta.
Además del error 405, como parte de la respuesta, el servidor debe añadir un encabezado
Además del error 405, como parte de la respuesta, el servidor debe añadir un encabezado
Allow
con una lista de métodos soportados:GET http://192.168.1.33:55678/api/example HTTP/1.1
HTTP/1.1 405 Method Not Allowed
Allow: POST, PUT
Y ahora, ahí van los enlaces recopilados durante la semana pasada que, como no podía ser de otra forma, viene cargado de novedades presentadas en el Build 2020. Espero que os resulten interesantes. :-)Por si te lo perdiste...
- Implementación de servicios gRPC con ASP.NET Core
José María Aguilar - Añadir automáticamente maxlength a inputs usando tag helpers en ASP.NET Core MVC
José María Aguilar
.NET Core / .NET
- Cómo manejar trazas en .Net Core con Serilog & Como manejar las trazas de una aplicación .Net Core con Seq y Serilog
Jorge Turrado - Reducir y Reutilizar código con paquetes Nuget
Joaquín García - Announcing .NET 5 Preview 4 and our journey to one .NET
Scott Hunter - Welcome to C# 9.0
Mads Torgersen - COVID-19 Delays Unifying .NET 5 Features
David Ramel - The rise of the Null-Object pattern in C# 8
Vlad Vizitiu - Mystery of The French Thousands Separator
Phil Haack - Microsoft Feature Flags: Controlling Features with Feature Filters (Microsoft.FeatureManagement)
Jason Roberts - Configuring Dependency Injection in .NET Core Console Applications
Karthik Chintala - Don't use method with side-effect in LINQ
Gérald Barré - Multi-path cancellation; a tale of two codependent async enumerators
Marc Gravell - Windows Forms Designer for .NET Core Released
Olia Gavrysh - C# 9 Simplified Console Apps
Steve Fenton - JSON handling made easy with System.Net.Http.Json
Marco Minerva - C# 9 Initializers and Immutability Steve Fenton
- BackgroundService Gotcha: Startup
Stephen Cleary - Effectively stubbing remote HTTP API services with HttpClient Interception
Joseph Woodward - Find The Next Number In A Sequence With C#
Khalid Abuhakmeh - Tackle Big-O Notation in .NET Core
Camilo Reyes
ASP.NET Core / ASP.NET
- Blazor WebAssembly 3.2.0 now available
Daniel Roth - ASP.NET Core updates in .NET 5 Preview 4
Sourabh Shirhatti - Introducing YARP Preview 1
Sam Spencer - Binding and Validating Enums in ASP.NET Core
Ben Foster - gRPC & ASP.NET Core 3.1: Message validation
Anthony Giretti - Handling Web API Exceptions with ProblemDetails middleware
Andrew Lock - Implementing always signed in with ASP.NET Core and Azure
Thomas Ardal - Hosting an ASP.NET Core App on Docker with HTTPS
Changhui Xu - Tag Helper Authoring in ASP .NET Core 3.1
Shahed Chowdhuri - How easy is it to build a Marvel search engine with Blazor?
Jon Hilton - Create Real-time Applications with ASP.NET Core SignalR – Using Rider!
Rachel Appel - Hosting Blazor WebAssembly in Azure Static Web Apps (Preview)
Tim Heuer - Logging to Notepad window from ASP.NET Core
Gunnar Peipman - Understand Searched Locations For The Razor View Engine And ASP.NET
Khalid Abuhakmeh
martes, 19 de mayo de 2020
Normalmente, en demos y ejemplos de Blazor solemos ver el uso componentes sin cuerpo, muchas veces escritos en forma de tags autocerrados, como los siguientes:
<Article Title="A new hope" DatePublished="@DateTime.Now"></Article>
<Article Title="A new hope" DatePublished="@DateTime.Now" />
El código de este componente, en Article.razor
, podría ser el siguiente:<h1>@Title</h1>
<p>Post content goes here...</p>
@code {
[Parameter]
public string Title { get; set; }
[Parameter]
public DateTime DatePublished { get; set; }
}
En este punto, es lógico pensar que nuestro artículo tendrá su texto, por lo que deberíamos poder incluirle un cuerpo. Una posibilidad sería incluir en el componente una propiedad Body
y enviarle el cuerpo en el momento de su instanciación, como en el ejemplo que vemos a continuación:<Article Title="A new hope" DatePublished="@DateTime.Now" Body="This is the post content..."></Article>
Pero, como podréis imaginar, esto es bastante limitado. Aparte de la legibilidad nula que tendría a nivel de código si el texto es medianamente extenso, no podríamos utilizar marcado HTML ni otros componentes Blazor en su interior, por lo que no es una solución práctica. Lo que en realidad nos interesa es poder hacer lo siguiente:<Article Title="A new hope" DatePublished="@DateTime.Now">
<p>This is the post content</p>
<p>Blah, blah, blah...</p>
</Article>
Sin embargo, si probáis a ejecutar el código anterior obtendréis un error parecido al siguiente:InvalidOperationException: Object of type 'MyBlazorProject.Pages.Article' does not have a property matching the name 'ChildContent'.El mensaje de error no nos indica por qué ocurre, aunque apunta en la dirección para poder solucionarlo. Como no podría ser de otra forma, Blazor permite la creación de componentes con cuerpo.
lunes, 18 de mayo de 2020
El popular código de estado HTTP 404 (Not found) indica que la conexión con el servidor ha podido ser establecida, pero el recurso solicitado no existe o bien el servidor prefiere hacer ver que no existe, quizás por razones de seguridad. Por defecto, este resultado puede ser cacheado en el cliente o elementos intermedios, salvo que se indique lo contrario.
Sin embargo, atendiendo a la especificación del protocolo HTTP, no siempre se utiliza correctamente. Por definición, la respuesta 404 no dispone de mecanismos para indicar si el recurso existió alguna vez o si el error es permanente o transitorio, mientras que el código HTTP 410 (Gone) sí permite expresar que el recurso existió, pero ya no está disponible y no volverá a estarlo, por lo que los clientes podrían eliminar enlaces o referencias al mismo con tranquilidad.
Y ahora, vamos a por los enlaces recopilados durante la semana pasada que, como es habitual, espero que os resulten altamente interesantes. :-)
Sin embargo, atendiendo a la especificación del protocolo HTTP, no siempre se utiliza correctamente. Por definición, la respuesta 404 no dispone de mecanismos para indicar si el recurso existió alguna vez o si el error es permanente o transitorio, mientras que el código HTTP 410 (Gone) sí permite expresar que el recurso existió, pero ya no está disponible y no volverá a estarlo, por lo que los clientes podrían eliminar enlaces o referencias al mismo con tranquilidad.
Y ahora, vamos a por los enlaces recopilados durante la semana pasada que, como es habitual, espero que os resulten altamente interesantes. :-)
Por si te lo perdiste...
- Generar rutas en minúsculas desde ASP.NET Core MVC
José María Aguilar - Cómo hacer que Fiddler inicie sin capturar conexiones
José María Aguilar
.NET Core / .NET
- Writing More Succinct C#
Dan Clarke - Integration Testing of a .NET Core Application with a Database Dependency
Daan Acohen - How WireMock.NET Can Help in Doing Integration Testing of a .NET Core Application
Daan Acohen - How to Improve .Net Applications with AOP
Daniele Fontani - Demystifying Memory Profilers in C# .NET Part 3: Memory Pressure
Michael Shpilt - Get the result of multiple tasks in a ValueTuple and WhenAll
Gérald Barré - Multi RDP Client .NET
Jayson Ragasa - Performance best practices in C#
Kevin Gosse - Use CancellationToken, not Thread.Sleep
Thomas Roll - A Story About .csproj, Large Solutions and Memory Usage
Maarten Balliauw - In-App scripts with C# & Roslyn
Mike James - Chain Actions, Funcs, and Predicates In .NET
Khalid Abuhakmeh - It’s all in the Host Class – Dependency Injection with .NET
Christian Nagel - More fun with comments
Matt Lacey - Things every C# developer should know
Thomas Levesque - The anatomy of async iterators (aka await, foreach, yield)
Marc Gravell
martes, 12 de mayo de 2020
En Blazor Server, cada usuario que esté utilizando la aplicación establece una conexión SignalR para enviar al servidor sus interacciones con la página, así como para retornar de vuelta al usuario las modificaciones del DOM realizadas desde el servidor. Esta conexión, junto con la información del estado del cliente almacenada en el servidor, es lo que en Blazor Server se denomina un "circuito".
Y ya que el servidor es consciente en todo momento de los usuarios conectados, en teoría debería ser posible contarlos para, por ejemplo, mostrarlos en pantalla como en la siguiente captura:
En este post vamos a ver cómo conseguir precisamente eso: incluir en las páginas del proyecto un contador de usuarios conectados que irá actualizándose en tiempo real, para, por el camino, profundizar un poco en el ciclo de vida de los circuitos de Blazor Server.
Y ya que el servidor es consciente en todo momento de los usuarios conectados, en teoría debería ser posible contarlos para, por ejemplo, mostrarlos en pantalla como en la siguiente captura:
En este post vamos a ver cómo conseguir precisamente eso: incluir en las páginas del proyecto un contador de usuarios conectados que irá actualizándose en tiempo real, para, por el camino, profundizar un poco en el ciclo de vida de los circuitos de Blazor Server.
lunes, 11 de mayo de 2020
Cuando una petición retorna un código de estado HTTP 403 (Forbidden), quiere decir que ésta fue realizada correctamente, pero el cliente no está autorizado para acceder al recurso o servicio que se intenta utilizar. Quizás porque la petición no incluyó las credenciales correctas, o tal vez porque eran insuficientes para acceder a él, pero la petición no debe ser repetida porque el resultado será el mismo.
A veces se confunde con el HTTP 401, pero son muy diferentes:
A veces se confunde con el HTTP 401, pero son muy diferentes:
- HTTP 401 (Unauthorized) indica, a pesar de su nombre, un problema de autenticación, y debe evaluarse antes de decidir si el usuario tiene acceso o no al recurso concreto.
- HTTP 403 (Forbidden) indica un problema de autorización, y es más específico que el anterior porque indica que el servidor sabe quién es el cliente y conoce el recurso al que intenta acceder, pero decide que no está autorizado a hacerlo.
Por si te lo perdiste...
-
Hace unos días me entrevistaron en la Resistencia Tecnológica, el divertido programa de Crossdvlup guiado por Alberto Díaz (@adiazcan), David Vidal (@D_Vid_45) y Sergio Hernández (@shmancebo). Algo más de hora y media charlando sobre la vida, el blog, ASP.NET, Blazor y algunas otras cosillas, que podéis ver en Youtube.
Aparte, os recomiendo suscribiros al canal y echar un vistazo a los programas anteriores, porque podréis encontrar temas muy interesantes y personajes ilustres :)
.NET Core / .NET
- Shallow Copy y Deep Copy en C#
Jorge Serrano - C# Source Generators: Less Boilerplate Code, More Productivity
Jason Roberts - Unit testing a Roslyn Analyzer
Antão Almada - Cómo ejecutar pruebas de código dentro de contenedores Docker
Jorge Turrado - How to implement full-text search in .Net application with Elasticsearch
Daniele Fontani - .NET Portability Analyzer
Derek Comartin - Ping a Server Using C#
Khalid Abuhakmeh - Post-Build Events and .NET Core & Cross-Platform Build Events in .NET Core using MSBuild
Jeremy Clark - Static Constructor Failures and Declaration Order
Rick Strahl - C# 8.0 nullable references: getting started in an existing codebase
Ian Griffiths - Ignore Specific files for a target framework on C#
Tsuyoshi Ushio - C#8 Using Declarations With FluentAssertions
Adam Storr
miércoles, 6 de mayo de 2020
Hace pocos días celebraba con vosotros el décimo aniversario de la serie enlaces interesantes y su entrada número 400, y hoy vengo con otra buena noticia: ¡Variable not found cumple 14 años!
Durante todo este tiempo, el blog ha formado parte de mi vida, y quiero creer que de algunas de las vuestras, aunque sea a pequeña escala. Esos minutillos que echáis los lunes para hacer vuestra propia selección de mis enlaces interesantes, cuando llegáis a él buscando cualquier asunto en Google, las veces que comentáis los contenidos, o cuando contactáis conmigo gracias a esta pequeña ventana en la red son la gasolina que hace que este motor que siga funcionando como el primer día.
Y es que después de 1.200 posts, más de mil comentarios y superando holgadamente los cuatro millones de páginas servidas, creo que aún nos queda combustible para rato. Sigo disfrutando de plasmar por aquí lo que voy aprendiendo, y de poder aportar un pequeño granito de arena a la comunidad ayudando a alguien de vez en cuando :)
Tradicionalmente aprovecho el cumpleaños del blog para echar un vistazo atrás y analizar cómo ha ido la cosa, así que allá vamos...
Durante todo este tiempo, el blog ha formado parte de mi vida, y quiero creer que de algunas de las vuestras, aunque sea a pequeña escala. Esos minutillos que echáis los lunes para hacer vuestra propia selección de mis enlaces interesantes, cuando llegáis a él buscando cualquier asunto en Google, las veces que comentáis los contenidos, o cuando contactáis conmigo gracias a esta pequeña ventana en la red son la gasolina que hace que este motor que siga funcionando como el primer día.
Y es que después de 1.200 posts, más de mil comentarios y superando holgadamente los cuatro millones de páginas servidas, creo que aún nos queda combustible para rato. Sigo disfrutando de plasmar por aquí lo que voy aprendiendo, y de poder aportar un pequeño granito de arena a la comunidad ayudando a alguien de vez en cuando :)
Tradicionalmente aprovecho el cumpleaños del blog para echar un vistazo atrás y analizar cómo ha ido la cosa, así que allá vamos...
martes, 5 de mayo de 2020
Normalmente un componente Blazor declara parámetros para permitir que otros componentes o páginas que lo utilicen puedan pasarle la información que necesita para funcionar.
Por ejemplo, el siguiente código en el interior de un componente definiría un par de propiedades llamadas
Por ejemplo, el siguiente código en el interior de un componente definiría un par de propiedades llamadas
Text
y Repeat
, que utiliza para repetir un texto tantas veces como se le indique:@* File: Repeater.razor *@
@for (var i = 0; i < Repeat; i++)
{
<p>@Text</p>
}
@code {
[Parameter]
public string Text { get; set; }
[Parameter]
public int Repeat { get; set; }
}
De esta forma, podríamos utilizar el componente desde otros puntos de la aplicación suministrándole los valores necesarios en cada caso:<Repeater Text="Hola" Repeat="6" />
Sin embargo, alguna vez podría resultar interesante poder obtener todos los parámetros que se han enviado a un componente, pero sin necesidad de conocerlos previamente.
lunes, 4 de mayo de 2020
El (relativamente desconocido) código de estado HTTP 402 (Payment required) se reservó para usos futuros hace más de veinte años, pensando que en algún momento se utilizaría para indicar al lado cliente que la operación solicitada requería "pasar por caja" antes de ser ejecutada.
Sin embargo, la idea nunca se desarrolló y, a falta de una especificación formal, no se generalizó su uso. Personalmente, jamás he implementado una API o servicio que retorne HTTP 402, pero hay algunos proveedores de servicios que sí lo hacen, aunque de forma arbitraria y no normalizada.
Esta era la píldora cultural del día, vamos con el tema que nos ocupa :)
Seguimos de encierro una semana más, aunque ya con la posibilidad de disfrutar de pequeños paseos (limitados en tiempo y distancia) o de hacer deporte en el exterior. Esto hace que el futuro se vea con algo más de optimismo, aunque espero que esta tímida apertura no provoque una vuelta atrás en los avances conseguidos hasta el momento.
Y mientras la cosa se aclara, podéis ir echando un vistazo a los enlaces recopilados durante la semana pasada que, como de costumbre, espero que os resulten interesantes. :-)
Sin embargo, la idea nunca se desarrolló y, a falta de una especificación formal, no se generalizó su uso. Personalmente, jamás he implementado una API o servicio que retorne HTTP 402, pero hay algunos proveedores de servicios que sí lo hacen, aunque de forma arbitraria y no normalizada.
Esta era la píldora cultural del día, vamos con el tema que nos ocupa :)
Seguimos de encierro una semana más, aunque ya con la posibilidad de disfrutar de pequeños paseos (limitados en tiempo y distancia) o de hacer deporte en el exterior. Esto hace que el futuro se vea con algo más de optimismo, aunque espero que esta tímida apertura no provoque una vuelta atrás en los avances conseguidos hasta el momento.
Y mientras la cosa se aclara, podéis ir echando un vistazo a los enlaces recopilados durante la semana pasada que, como de costumbre, espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Limpiar la clase Startup de ASP.NET Core
José María Aguilar - Enumerables asíncronos en C# 8
José María Aguilar
.NET Core / .NET
- Cómo escribir información adicional de salida en nuestros tests de xUnit
Jorge Serrano - Web scraping de una página web y conversión a pdf con .NET Core 3.1
Jorge Serrano - Work flow of diagnosing memory performance issues – Part 2
Maoni Stephens - Introducing C# Source Generators
Phillip Carter - Did you know ? Easy and custom debugging with DebuggerDisplay and DebuggerTypeProxy attributes on Visual Studio
Anthony Giretti - Dotnet core 3.0 Self Contained Single Executable (and other build optimisations)
Darren Horrocks - The Dispose Pattern is Broken
Paulo Zemek - Demystifying Memory Profilers in C# .NET Part 2
Michael Shpilt - Exception Helper – Rethrown Exceptions
Andy Sterland - How to use CancellationTokens to cancel operations in the Azure SDK for .NET
Adrian Hall - Split a string into lines without any allocation
Gérald Barré - INotifyPropertyChanged with C# 9.0 Source Generators
Jerome Laban - Performance in .NET – Part 4
Ricardo Peres - Access to EXIF tags in JPEG files
Hans-Peter Kalb - C# 8.0 nullable references: inferred (non-)nullness
Ian Griffiths - Markdown .NET Core Library
Jason Gaylord