Autor en Google+
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 ;)

14 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!
jueves, 9 de julio de 2020

La palabra vacaciones, derivada del latín vacans, participio del verbo vacare (estar libre, desocupado), está definida por la RAE como "Período del año en el que los trabajadores descansan temporalmente del trabajo". Y creo que ha llegado la hora de aplicarla, aunque no sea en toda su extensión :)

Como es habitual por estas fechas, os informo que la semana que viene iniciaré mi descanso veraniego, y el blog quedará en modo de bajo consumo hasta septiembre. Durante este tiempo seguiré trabajando en otras cosas (tengo grandes proyectos en curso, ya os iré contando ;)) pero al menos podré hacer jornadas más cortas y descansar un poco los fines de semana, que falta hace.

¡Nos vemos a la vuelta!

Playa
Playa de Costa Ballena, Rota (Cádiz). Imagen: Hotel Elba

Publicado en Variable not found.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 7 de julio de 2020
Blazor En esta serie sobre interoperación Javascript-Blazor hemos ido viendo cómo desde Blazor Server o WebAssembly podíamos llamar a funciones Javascript disponibles en el browser, y también cómo conseguir invocar métodos estáticos .NET desde Javascript.

Como recordaréis del post anterior, la invocación de métodos estáticos era bastante sencilla, porque básicamente desde Javascript sólo teníamos que conocer el nombre del ensamblado donde se encontraba el código y el nombre del método a ejecutar. El hecho de que el método fuera estático es una ventaja, pues no hay "piezas móviles" en el puzzle.

Sin embargo, si desde Javascript queremos invocar un método de instancia, la cosa se complica un poco porque tendremos que ayudar a Blazor a determinar de qué instancia se trata, y esto a priori no suena sencillo porque Javascript y Blazor viven en dos mundos diferentes (de hecho, en el caso de Blazor Server incluso están físicamente separados). Sin embargo, veremos que las herramientas que ofrece el framework son suficientes para llevarlo a cabo sin liarnos demasiado.

Esta última entrega la dedicaremos precisamente a esto: aprender cómo podemos llamar desde Javascript a métodos de instancia escritos en C#.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 6 de julio de 2020
Enlaces interesantes

El código de estado HTTP 411, length required, es enviado al cliente para indicar que la petición no puede ser aceptada si no incluye el encabezado content-length indicando el tamaño en bytes del cuerpo de la misma.

Ahí van los enlaces recopilados durante la semana pasada, la última entrega antes de comenzar las vacaciones. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

jueves, 2 de julio de 2020
MVP*10Es una alegría, un honor y un auténtico lujo poder compartir con todos vosotros que, por décimo año consecutivo, he sido reconocido por Microsoft como Most Valuable Professional (MVP) en la categoría Developer technologies.

Cuando fui nombrado MVP por primera vez, jamás pensé que este privilegio fuera a durar tanto. Un par de añitos quizás, lo suficiente como para poder visitar Redmond alguna vez y poder contar a los nietos que "yo estuve allí" ;) Pero diez años más tarde, aquí estamos todavía, con las mismas ganas y entusiasmo de poder seguir formando parte de este club de amigos a los que sigo y admiro tanto. ¡Impresionante!

Esta vez la notificación me ha pillado en una videollamada con el gran Jorge Turrado, amigo y compañero MVP, que me ha sacado del fragor de la batalla diaria para inyectarme la dosis de adrenalina que supone darse cuenta de pronto de que hoy era el día de nombramientos y todavía no me había llegado el famoso email :D Por cierto, Jorge ¡felicidades, por tu merecida renovación!

Muchas gracias a todos los que hacéis posible que me lleve estos momentazos. A los amigos y amigas de blog, porque sin su apoyo no habría sido posible llegar hasta tan lejos; al equipo del programa MVP, por su incansable labor y exquisito trato con todos, y, por supuesto, a mis tres niñas, por consentírmelo todo :)

Finalmente, no me gustaría cerrar este post sin enviar mi más sincera enhorabuena a los nuevos MVP; disfrutad de ese momento tan bonito. Si renováis en el futuro os llevaréis grandes alegrías, pero la primera vez nunca se olvida. Y también enviar un fuerte abrazo (con distancia social, eso sí ;)) a los que repetís galardón: como ya he dicho alguna vez, lo difícil no es sólo llegar, sino también mantenerse.

Publicado en Variable not found.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 30 de junio de 2020
Unable to connect to web server 'IIS Express'

Va un post rapidito, pero que seguro que puede ahorrar quebraderos de cabeza a más de uno que se encuentre con este problema al iniciar desde Visual Studio una aplicación ASP.NET, ASP.NET Core MVC/Web API, Razor Pages, o incluso Blazor que utilicen por debajo IIS Express.

El problema ocurre justo al ejecutar la aplicación con F5 o Ctrl+F5 desde el entorno de desarrollo; en ese momento, la ejecución se detiene y aparece un cuadro de diálogo con el mensaje:

"Unable to connect to web server 'IIS Express'"

Creo que llevo años encontrándome de vez en cuando con este problema al arrancar las aplicaciones, y nunca entendí muy bien por qué pasaba. Buscaba por la red y solo encontraba soluciones relativas a eliminar el archivo de configuración applicationhost.config que Visual Studio guarda en la carpeta ".vs" de la solución, a reiniciar el IDE o incluso la máquina, abrirlo como Administrador, o cambiar el puerto en la configuración del proyecto, normalmente algunas unidades por arriba o por abajo que el puerto asignado inicialmente.

Esta última opción es la que más veces me ha funcionado, pero no siempre iba bien, por lo que al final tampoco la identifiqué como una clara receta para paliar el problema que nos ocupa.

Hace unos días me ha vuelto a ocurrir con un proyecto que uso muy a menudo, y, de un día para otro, ha dejado de funcionar y ha comenzado a lanzarme a la cara el maldito cuadro de diálogo. La diferencia es que por fin he podido encontrar una respuesta satisfactoria, al menos para alguno de los escenarios que pueden causar el error :)

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 29 de junio de 2020
Enlaces interesantes

Como ya adelantamos en la entrega 404 de enlaces interesantes, los códigos de estado 404 y 410 son muy similares, pues ambos permiten al servidor expresar que el recurso solicitado no existe.

La diferencia entre ambos es que HTTP 410 (Gone) que el recurso existió pero ya no está disponible, mientras que HTTP 404 no permite distinguir entre un recurso que jamás ha existido y uno que simplemente ha desaparecido.

Y ahora vamos con una nueva recopilación de enlaces que, como siempre, espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 23 de junio de 2020
Blazor
Hace poco veíamos mecanismos de interop que permitían invocar código Javascript desde Blazor, con objeto de poder seguir utilizando código existente en bibliotecas o componentes, ya sean nuestros o de terceros.

Pero Blazor también aporta mecanismos para la interoperación en sentido contrario, es decir, permitir que desde código Javascript podamos invocar métodos escritos en C#, ya sea con Blazor Server o Blazor WebAssembly.

De hecho, Blazor permite invocar métodos tanto estáticos como de instancia, aunque en este post nos centraremos sólo en los primeros porque son más sencillos de entender. En un artículo posterior profundizaremos en el segundo escenario.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 22 de junio de 2020
Enlaces interesantes

Usado frecuentemente en las respuestas a peticiones de tipo PUT, el código de estado HTTP 409 es retornado por el servidor para indicar que existe un conflicto con el estado actual del recurso destino de la petición, esperando que el cliente solucione el problema y reintente la operación. Como ayuda, en el cuerpo de la respuesta suele incluirse información que facilitaría al cliente la resolución del conflicto.

Un ejemplo podría ser cuando intentamos actualizar con PUT una entidad con un número de versión posterior al que estamos enviando, lo que indicaría que otra petición distinta modificó el recurso antes que nosotros.

Y ya sin conflictos, van los enlaces recopilados durante la semana pasada que, como no podía ser de otra forma, espero que os resulten interesantes :-)

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 16 de junio de 2020
Blazor Aunque uno de los objetivos de partida de Blazor es permitir que toda la lógica de presentación de una aplicación pueda ser implementada sin tocar una línea de Javascript, sería absurdo ignorar que este lenguaje dispone de uno de los ecosistemas más amplios y ricos del mundo del software. Sin duda, sería una pena (y un error) intentar ignorar la ingente cantidad de bibliotecas y componentes que existen para él.

Tampoco podemos olvidar que puede que nosotros mismos tengamos bibliotecas Javascript que nos podría interesar reutilizar en nuevas interfaces de usuario. De nuevo, sería un error que el hecho de saltar a Blazor nos obligara a reescribir todo desde cero.

Por estas razones Blazor dispone de mecanismos para interoperar con Javascript bidireccionalmente, pues:
  • desde nuestras aplicaciones Blazor podemos invocar funciones Javascript,
  • y desde Javascript podemos invocar métodos escritos en C# con Blazor.
En este post vamos a centrarnos en la primera posibilidad, dejando la segunda para otras publicaciones de la serie que llegarán más adelante.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 15 de junio de 2020
Enlaces interesantes

Seguimos comentando los códigos de estado HTTP que coinciden con el número de entrega de la serie enlaces interesantes, y en esta ocasión le ha llegado el turno al HTTP 408.

Este código de estado es enviado por un servidor cuando cierra una conexión debido a que se ha superado el tiempo de espera máximo establecido para recibir una petición, es decir, se ha producido un timeout antes de que la petición haya terminado de llegar. En estos casos, el error suele ir acompañado de un encabezado Connection con el valor close, que indica que el servidor desea cerrar la conexión:

HTTP/1.1 408 Request timeout
Connection: close

Y ahora, ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

Eventos

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 9 de junio de 2020
Blazor En este post vamos a echar un vistazo a algo muy básico, pero que seguro que ayuda a los que estáis comenzando con Blazor para haceros una mejor idea su funcionamiento: cómo mostrar u ocultar elementos en la página.

La idea sería conseguir que, en el siguiente componente, la pulsación del botón etiquetado como "Toggle" haga que el bloque <div> donde se encuentra el "Hello world!" se oculte y se muestre sucesivamente:
<h1>Visibility demo</h1>
<div>
    <h2>Hello world!</h2>
</div>

<button class="btn btn-primary" @onclick="Toggle">Toggle</button>

@code {
    private bool _isVisible = true;

    private void Toggle()
    {
        _isVisible = !_isVisible;
    }
}
Como es de esperar, al ejecutar este código veremos que cuando el elemento está visible aparece tanto en la página como en los elementos de la misma (es decir, en el DOM):

El elemento aparece en la página y en el DOM

Como en otros marcos de trabajo para la construcción de webs SPA, con Blazor podemos utilizar distintas técnicas para mostrar u ocultar elementos:
  • Añadiendo o eliminando físicamente el elemento del DOM.
  • Utilizando estilos en línea que modifiquen su visibilidad.
  • Aplicando clases CSS que modifiquen su visibilidad.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 8 de junio de 2020
Enlaces interesantes

El (desconocido, al menos para mí) código de estado HTTP 407 es enviado al cliente cuando la petición que intentó no pudo ser completada debido a que un proxy requiere autenticación. Cuando este error se recibe, viene acompañado de un encabezado Proxy-Authenticate con información sobre cómo autenticarse.

Y ahora, ahí van los enlaces recopilados durante la semana pasada, que espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 2 de junio de 2020
Blazor La verdad es que el mensaje "Loading..." que aparece en el navegador mientras la aplicación Blazor WebAssembly está cargando es bastante insulso: un fondo blanco, con el texto sin estilo alguno. Es cierto que aparece sólo unos segundos, y a veces mucho menos que eso, pero si queremos que nuestra aplicación tenga un aspecto profesional, deberíamos hacer algo por mejorarlo.

Veamos cómo.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 1 de junio de 2020
Enlaces interesantes

El código de estado HTTP 406 (Not Acceptable), es retornado por los servidores cuando no pueden generar una respuesta debido a que son incapaces de cumplir las condiciones indicadas en los encabezados de negociación de contenidos (Accept, Accept-Charset, Accept-Encoding y Accept-Language). Por ejemplo, podríamos obtenerlo si solicitásemos un recurso especificando application/json en el encabezado Accept, pero el servidor no fuera capaz de generar una representación del contenido en dicho formato.

Y ahora, vamos a por los enlaces recopilados durante la semana pasada, que espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 25 de mayo de 2020
Enlaces interesantes 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 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...

.NET Core / .NET

ASP.NET Core / ASP.NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 19 de mayo de 2020
Blazor 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.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 18 de mayo de 2020
Enlaces interesantes 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. :-)

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 12 de mayo de 2020
Blazor 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:

Aplicación Blazor mostrando el número de usuarios conectados

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.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 11 de mayo de 2020
Enlaces interesantes 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:
  • 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.
Y dicho esto, vamos a por nuestra ración de enlaces que, como es habitual, espero que os resulten interesantes :)

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

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

miércoles, 6 de mayo de 2020
Fuegos artificiales 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...

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 5 de mayo de 2020
Blazor 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 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.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 4 de mayo de 2020
Enlaces interesantes 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. :-)

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 28 de abril de 2020
Blazor Hoy va un truquillo rápido sobre Blazor que puede resultar útil en muchos escenarios. Como probablemente sepáis, al igual que ocurre con otras tecnologías, Blazor codifica la salida HTML por motivos de seguridad, de forma que cualquier contenido con código de marcado será mostrado por defecto tal cual, sin interpretar las etiquetas.

Por ejemplo, considerad el siguiente código en un componente Blazor:
<p>This text is encoded: @myHtml</p>

@code {
    string myHtml = "Hello, <b>this is bold</b>";
}
El resultado que enviaremos al navegador es el siguiente:
<p>This text is encoded: Hello, &lt;b&gt;this is bold&lt;/b&gt;</p>
Y, por tanto, nuestros usuarios podrán leer literalmente este párrafo:
This text is encoded: Hello, <b>this is bold</b>
Normalmente no es eso lo que queremos mostrarles, ¿verdad?

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 27 de abril de 2020
Enlaces interesantes Aunque seguimos en el túnel, parece que tímidamente está apareciendo un poco de luz en la lejanía. Y mientras la cosa se ilumina del todo, quizás os entretengan un rato los enlaces recopilados durante la semana pasada, que, como de costumbre, espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 21 de abril de 2020
Blazor Es lógico pensar que muchas de las aplicaciones que construyamos con Blazor, sobre todo en el mundo empresarial, necesitarán acceder a bases de datos para obtener o almacenar información.

En caso de utilizar Blazor WebAssembly, ese acceso encajará conceptualmente con lo que venimos haciendo desde hace años al construir aplicaciones SPA: desde el lado cliente simplemente llamaremos a una API o endpoint que actuará como pasarela, por lo que todo el código de acceso a datos se encontrará en el servidor. Aunque existen algunas iniciativas para posibilitar que EF Core funcione directamente en el navegador con algunos proveedores, ciertamente no será el escenario habitual.

Sin embargo, si utilizamos Blazor Server, tendremos la sensación inicial de que es todo más sencillo. El código de eventos bindeados a la interfaz se ejecuta en servidor, por lo que a priori sólo tendríamos que replicar lo que solemos hacer con servicios o controladores: solicitar una instancia del contexto de datos al inyector de dependencias, y utilizarla para lograr nuestros propósitos.

Pero no, la cosa es algo más complicada que eso. De hecho, los que ya estéis creando aplicaciones Blazor Server con EF Core seguro que os habéis topado en algún momento con un error como el siguiente:
InvalidOperationException: A second operation started on this context before a previous operation 
completed. This is usually caused by different threads using the same instance of DbContext. For 
more information on how to avoid threading issues with DbContext, see 
https://go.microsoft.com/fwlink/?linkid=2097913.
Esta excepción se debe a que existen dos hilos de ejecución utilizando la misma instancia del contexto de datos al mismo tiempo, algo que Entity Framework no permite. Esto ocurrirá, por ejemplo, si tenéis en la misma página varios componentes que de forma concurrente intentan acceder a la base de datos al inicializarse.

¿Por qué ocurre esto?

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 20 de abril de 2020
Enlaces interesantes Pues recién cumplidos los diez años desde que comencé a publicar enlaces de interés todas las semanas, vamos ahora a por la entrega número 400. Como siempre, espero que os resulten interesantes y os ayuden a llevar mejor estos días :)

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 14 de abril de 2020
Enlaces interesantes Es increíble lo rápido que pasa el tiempo: aunque parezca que fue ayer, hace ya diez años que comencé a publicar enlaces interesantes en el blog, iniciando la serie con el post Enlaces interesantes 1... y en estos momentos estoy preparando la entrega semanal número 400 :)

Y para celebrarlo, he pensado que estaría bien hacer un recopilatorio de preguntas y curiosidades que los fieles seguidores de esta serie me habéis ido haciendo llegar, tanto en persona como a través de redes sociales o mails, a lo largo de estos años.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 13 de abril de 2020
Enlaces interesantes Una semana más de confinamiento, pero una semana menos para que esta pesadilla termine. Y mientras tanto, sigamos compartiendo enlaces que, como de costumbre, espero que os resulten interesantes :)

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 6 de abril de 2020
Enlaces interesantes Dado que la recopilación de enlaces ha sido considerada una actividad esencial, no se ha visto afectada por el parón decretado recientemente, así que ahí va la cosecha de la semana pasada :)

Como siempre, espero que os resulten interesantes y os ayuden a llevar mejor el confinamiento. ¡Que paséis una buena Semana Santa!

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 31 de marzo de 2020
ASP.NET Core Como sabemos, hasta ASP.NET Core 2.2, registrábamos los servicios de MVC y Razor Pages en el método ConfigureServices() de la clase Startup con una línea como la siguiente:
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    ...
}
Esto era todo lo que necesitábamos para poder utilizar cualquiera de estas tecnologías en nuestra aplicación. Sin embargo, a partir de ASP.NET Core 3.0, nuestro intellisense se vio inundado de opciones adicionales como AddControllers(), AddRazorPages() AddControllersWithViews().

¿Para qué sirven, y por qué ha sido necesario introducir estos nuevos extensores?

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 30 de marzo de 2020
Enlaces interesantes Pues otra semana de encierro, y otro buen número de enlaces recopilados que, como de costumbre, espero que os resulten interesantes.

¡Cuidaos mucho!

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 24 de marzo de 2020
Blazor Al comenzar con Blazor, seguro que veis en la mayoría de ejemplos que la implementación de la lógica (código C#) y de la pura interfaz de usuario (HTML) se encuentran en un bloque @code en el mismo archivo .razor, como en el siguiente bloque de código:
@* File: ~/Pages/HelloWorld.razor *@
@page "/hello"
<h1>Hello</h1>
<div>
    <label for="name">Your name:</label>
    <input id="name" @bind-value="Name" @bind-value:event="oninput"/>
</div>
@if (HasName)
{
    <h2>Hello, @Name!</h2>
}

@code
{
    public string Name { get; set; }
    public bool HasName => !string.IsNullOrWhiteSpace(Name);
}
Sin embargo, esto no tiene que ser necesariamente así. En tiempo de compilación, un archivo .razor genera una clase parcial C# con su mismo nombre, lo cual nos brinda la posibilidad de mover todo el código C# a otra porción de dicha clase.
Podéis ver las clases generadas para cada archivo .razor en la carpeta del proyecto obj\debug\netcoreapp3.1\Razor\Pages.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 23 de marzo de 2020
Enlaces interesantes Ahí van los enlaces recopilados durante la semana pasada. Espero que os entretengan, al menos un ratillo, durante el confinamiento :-)

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 17 de marzo de 2020
.NET Core Hace unos días han anunciado la disponibilidad de una herramienta que os puede interesar si, como un servidor, acumuláis un gran número de versiones del SDK y runtimes de .NET Core que no váis a necesitar, algo muy propio de ese Diógenes digital que todos llevamos dentro ;)

El estado actual de acumulación de SDKs podéis conocerlo muy fácilmente desde línea de comandos utilizando la orden dotnet --list-sdks:
C:\>dotnet --list-sdks
1.1.11 [C:\Program Files\dotnet\sdk]
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.503 [C:\Program Files\dotnet\sdk]
2.1.504 [C:\Program Files\dotnet\sdk]
2.1.505 [C:\Program Files\dotnet\sdk]
2.1.507 [C:\Program Files\dotnet\sdk]
2.1.508 [C:\Program Files\dotnet\sdk]
2.1.509 [C:\Program Files\dotnet\sdk]
2.1.511 [C:\Program Files\dotnet\sdk]
2.1.602 [C:\Program Files\dotnet\sdk]
2.1.604 [C:\Program Files\dotnet\sdk]
2.1.700 [C:\Program Files\dotnet\sdk]
2.1.701 [C:\Program Files\dotnet\sdk]
2.1.800-preview-009696 [C:\Program Files\dotnet\sdk]
2.1.801 [C:\Program Files\dotnet\sdk]
2.1.802 [C:\Program Files\dotnet\sdk]
2.2.102 [C:\Program Files\dotnet\sdk]
2.2.105 [C:\Program Files\dotnet\sdk]
2.2.202 [C:\Program Files\dotnet\sdk]
2.2.203 [C:\Program Files\dotnet\sdk]
2.2.204 [C:\Program Files\dotnet\sdk]
3.0.100-preview8-013656 [C:\Program Files\dotnet\sdk]
3.0.100-preview9-014004 [C:\Program Files\dotnet\sdk]
3.0.100 [C:\Program Files\dotnet\sdk]
3.1.100 [C:\Program Files\dotnet\sdk]
3.1.101 [C:\Program Files\dotnet\sdk]
3.1.102 [C:\Program Files\dotnet\sdk]

C:\>_
En mi caso, tengo aún por ahí el SDK de .NET Core 1.x, un par de decenas de .NET Core 2.x, y algunas previews, pero los he visto mucho peores ;) Obviamente, salvo dos o tres versiones que quizás me interesen porque tengo aplicaciones que aún no he migrado, el resto ocupan en mi equipo un espacio considerable sin motivo, más de 5GB, pues cada SDK puede pesar entre 150 y 200 Mb.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 16 de marzo de 2020
Enlaces interesantes Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes, ¡y que los veáis desde casa, que la cosa se está poniendo muy muy fea! ¡Cuidaos mucho!

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

martes, 10 de marzo de 2020
.NET Core Alguna vez he escuchado, a modo de leyenda urbana, que no era bueno utilizar try/catch porque el mero hecho de usar este tipo de bloque de código afectaba al rendimiento.

La verdad es que de forma intuitiva se puede adivinar que esto no debería ser así. Si no se producen excepciones en un código que tengamos envuelto en un try/catch se debería ejecutar virtualmente a la misma velocidad que si no usáramos este tipo de bloque. Cosa distinta es si producen excepciones: ahí el rendimiento sí se verá seriamente penalizado, pero no es culpa del try/catch sino del propio sistema de gestión de excepciones de .NET.

Pero claro, lo dicho anteriormente es sólo cierto si somos capaces de demostrarlo, así que usaremos nuestro viejo conocido BenchmarkDotnet para desmontar este mito.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 9 de marzo de 2020
Enlaces interesantes Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 2 de marzo de 2020
Enlaces interesantes Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET Core / .NET

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons