Novedades de ASP.NET Core 5.0

En este artículo se resaltan los cambios más importantes de ASP.NET Core 5.0, con vínculos a la documentación pertinente.

Mejoras en ASP.NET Core MVC y Razor

Enlace de modelos DateTime como UTC

El enlace de modelos admite ahora las cadenas de hora UTC de enlace para DateTime. Si la solicitud contiene una cadena de hora UTC, el enlace de modelos la enlaza a una DateTime UTC. Por ejemplo, la siguiente cadena de tiempo está enlazada a la hora UTC DateTime: https://example.com/mycontroller/myaction?time=2019-06-14T02%3A30%3A04.0576719Z

Enlace de modelos y validación con los nueve tipos de registro de C#

Los nueve tipos de registros de C# pueden usarse con el enlace de modelos en un controlador MVC o una página Razor. Los tipos de registros son una buena manera de modelar los datos que se transmiten a través de la red.

Por ejemplo, el PersonController siguiente usa el tipo de registro Person con el enlace de modelos y la validación de formularios:

public record Person([Required] string Name, [Range(0, 150)] int Age);

public class PersonController
{
   public IActionResult Index() => View();

   [HttpPost]
   public IActionResult Index(Person person)
   {
          // ...
   }
}

El archivo Person/Index.cshtml:

@model Person

Name: <input asp-for="Model.Name" />
<span asp-validation-for="Model.Name" />

Age: <input asp-for="Model.Age" />
<span asp-validation-for="Model.Age" />

Mejoras en DynamicRouteValueTransformer

ASP.NET Core 3.1 presentó DynamicRouteValueTransformer como una manera de usar un punto de conexión personalizado para seleccionar dinámicamente una acción del controlador MVC o una página Razor. ASP.NET Core 5.0 aplicaciones pueden pasar el estado a un DynamicRouteValueTransformer y filtrar el conjunto de puntos de conexión elegidos.

Varios

  • El atributo [Compare] se puede aplicar a las propiedades en un modelo de página de Razor.
  • Los parámetros y las propiedades enlazadas desde el cuerpo se consideran necesarios de forma predeterminada.

Web API

Especificación OpenAPI activada de forma predeterminada

La especificación OpenAPI es un estándar del sector para describir las API HTTP e integrarlas en procesos empresariales complejos o con terceros. OpenAPI es ampliamente compatible con todos los proveedores de nube y muchos registros de API. Las aplicaciones que emiten documentos de OpenAPI desde API web tienen una variedad de nuevas oportunidades en las que se pueden usar esas API. En colaboración con los mantenedores del proyecto de código abierto Swashbuckle.AspNetCore, la plantilla de API de ASP.NET Core contiene una dependencia de NuGet en Swashbuckle. Swashbuckle es un conocido paquete de NuGet de código abierto que envía documentos OpenAPI de forma dinámica. Swashbuckle lo hace examinando los controladores de la API y generando el documento OpenAPI en tiempo de ejecución, o en tiempo de compilación usando la CLI de Swashbuckle.

En ASP.NET Core 5.0, las plantillas de API web habilitan la compatibilidad con OpenAPI de forma predeterminada. Para deshabilitar OpenAPI:

  • Desde la línea de comandos:

      dotnet new webapi --no-openapi true
    
  • Desde Visual Studio: Desactive Habilitar la compatibilidad de OpenAPI.

Todos los archivos .csproj creados para los proyectos de API web contienen la referencia del paquete NuGet Swashbuckle. AspNetCore.

<ItemGroup>
    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.5.1" />
</ItemGroup>

El código generado por la plantilla contiene código en Startup.ConfigureServices que activa la generación de documentos OpenAPI:

public void ConfigureServices(IServiceCollection services)
{

    services.AddControllers();
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApp1", Version = "v1" });
    });
}

El método Startup.Configure agrega el middleware Swashbuckle, que permite:

  • El proceso de generación de documentos.
  • La página de interfaz de usuario de Swagger de forma predeterminada en modo de desarrollo.

El código generado por la plantilla no expone accidentalmente la descripción de la API al publicar en producción.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseSwagger();
        app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json",
                         "WebApp1 v1"));
    }

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Importación de Azure API Management

Cuando los proyectos API de ASP.NET Core habilitan OpenAPI, la publicación de la versión 16.8 y posteriores de Visual Studio 2019 proporciona automáticamente un paso adicional en el flujo de publicación. Los desarrolladores que usan Azure API Management tienen la oportunidad de importar automáticamente las API en Azure API Management durante el flujo de publicación:

Azure API Management Import VS publishing

Mejor experiencia de inicio para los proyectos de API web

Con OpenAPI habilitado de forma predeterminada, la experiencia de inicio de la aplicación (F5) para desarrolladores de API web mejora significativamente. Con ASP.NET Core 5.0, la plantilla de API web viene preconfigurada para cargar la página de la interfaz de usuario de Swagger. La página de la interfaz de usuario de Swagger proporciona la documentación agregada a la API publicada y permite probar las API con un solo clic.

swagger/index.html view

Blazor

Mejoras en el rendimiento

En el caso de .NET 5, hemos realizado mejoras significativas en el rendimiento del entorno de ejecución Blazor WebAssembly con un foco específico en la representación de la interfaz de usuario y la serialización de JSON complejos. En nuestras pruebas de rendimiento, Blazor WebAssembly en .NET 5 es dos a tres veces más rápido en la mayoría de los escenarios. Para más información, consulte el blog de ASP.NET: Actualizaciones de ASP.NET Core en .NET 5 Release Candidate 1.

Aislamiento de CSS

Blazor ahora admite la definición de estilos CSS cuyo ámbito es un componente determinado. Los estilos CSS específicos de los componentes facilitan el razonamiento de los estilos de una aplicación y evitan efectos secundarios no intencionados de los estilos globales. Para más información, vea Aislamiento de CSS de Blazor de ASP.NET Core.

Nuevo componente de InputFile

El componente InputFile permite leer uno o varios archivos seleccionados por un usuario para cargarlos. Para más información, vea Cargas de archivos de Blazor en ASP.NET Core.

Nuevos componentes InputRadio y InputRadioGroup

Blazor tiene los componentes integrados InputRadio y InputRadioGroup que simplifican el enlace de datos a grupos de botones de radio con validación integrada. Para obtener más información, consulte Componentes de entrada de ASP.NET Core Blazor.

Virtualización de componentes

Mejore el rendimiento percibido de la representación de componentes usando la compatibilidad de virtualización integrada del marco Blazor. Para más información, vea Virtualización de componentes Razor de ASP.NET Core.

Compatibilidad con eventos ontoggle

Los eventos Blazor ahora admiten el evento DOM ontoggle. Para más información, vea Control de eventos de Blazor en ASP.NET Core.

Establecimiento del foco de la interfaz de usuario en aplicaciones Blazor

Use el método de conveniencia FocusAsync en las referencias de elemento para establecer el foco de la interfaz de usuario en ese elemento. Para más información, vea Control de eventos de Blazor en ASP.NET Core.

Atributos de clase CSS de validación personalizados

Los atributos de clase CSS de validación personalizados son útiles al integrar con marcos de CSS, como Bootstrap. Para obtener más información, consulte Validación de formularios de ASP.NET Core Blazor.

Compatibilidad con IAsyncDisposable

Los componentes de Razor ahora admiten la interfaz de IAsyncDisposable para la versión asincrónica de los recursos asignados.

Aislamiento de JavaScript y referencias a objetos en

Blazor permite el aislamiento de JavaScript en módulos de JavaScript estándar. Para más información, vea Llamada a funciones de JavaScript desde métodos de .NET en Blazor de ASP.NET Core.

Nombre para mostrar de la compatibilidad de componentes de formulario

Los siguientes componentes integrados admiten nombres para mostrar con el parámetro DisplayName:

  • InputDate
  • InputNumber
  • InputSelect

Para obtener más información, vea Introducción a los formularios de ASP.NET CoreBlazor.

Parámetros de ruta de captura general

Los parámetros de ruta de captura general, que capturan rutas de acceso en varios límites de carpeta, se admiten en los componentes. Para más información, vea Enrutamiento y navegación de Blazor de ASP.NET Core.

Mejoras en la depuración

La depuración de aplicaciones Blazor WebAssembly ha mejorado en ASP.NET Core 5.0. Además, ahora se admite la depuración en Visual Studio para Mac. Para más información, vea Depuración de aplicaciones de BlazorASP.NET Core.

Microsoft Identity v2.0 y MSAL v2.0

La seguridad de Blazor ahora usa Microsoft Identity v2.0 (Microsoft.Identity.Web y Microsoft.Identity.Web.UI) y MSAL v2.0. Para más información, consulte los temas de la seguridad de Blazor y del nodo Identity.

Almacenamiento de explorador protegido para Blazor Server

Las aplicaciones de Blazor Server ahora pueden usar la compatibilidad integrada para almacenar el estado de la aplicación en el explorador que se ha protegido contra la manipulación mediante la protección de datos de ASP.NET Core. Los datos se pueden almacenar en el almacenamiento de explorador local o en el almacenamiento de sesión. Para más información, vea Administración de estado de Blazor en ASP.NET Core.

Representación previa de Blazor WebAssembly

La integración de componentes se ha mejorado en los modelos de hospedaje y las aplicaciones de Blazor WebAssembly ahora pueden representar la salida en el servidor.

Mejoras en el recorte o la vinculación

Blazor WebAssembly realiza la vinculación o recorte del lenguaje intermedio (IL) durante una compilación para recortar el lenguaje intermedio innecesario de los ensamblados de salida de la aplicación. Con la versión de ASP.NET Core 5.0, Blazor WebAssembly realiza un recorte mejorado con opciones de configuración adicionales. Para más información, vea Configuración del recortador de ASP.NET Core Blazor y Opciones de recorte.

Analizador de compatibilidad con el explorador

Las aplicaciones Blazor WebAssembly tienen como destino el área expuesta de la API de .NET completa, pero no todas las API de .NET son compatibles con WebAssembly, debido a las restricciones de espacio aislado del explorador. Las API no compatibles inician la excepción PlatformNotSupportedException cuando se ejecutan en WebAssembly. Un analizador de compatibilidad de plataforma advierte al desarrollador cuando la aplicación usa API que no son compatibles con las plataformas de destino de la aplicación. Para obtener más información, vea Consumo de componentes Razor de ASP.NET Core a partir de una biblioteca de clases de Razor (RCL).

Ensamblados de carga diferida

Se puede mejorar el rendimiento de inicio de la aplicación Blazor WebAssembly aplazando la carga de algunos ensamblados de la aplicación hasta que sean necesarios. Para más información, vea Ensamblados de carga diferida en Blazor WebAssembly de ASP.NET Core.

Compatibilidad de globalización actualizada

La compatibilidad con la globalización está disponible para Blazor WebAssembly basada en componentes internacionales para Unicode (ICU). Para más información, vea Globalización y localización de Blazor de ASP.NET Core.

gRPC

Se han realizado muchas mejoras de conformidad en gRPC. Para más información, consulte Mejoras de rendimiento de gRPC en .NET 5.

Para obtener más información sobre gRPC, vea Introducción a gRPC en .NET.

SignalR

Filtros de concentrador de SignalR

Los filtros del concentrador SignalR, denominados canalizaciones de concentrador en ASP.NET SignalR, es una característica que permite que el código se ejecute antes y después de que se llame a los métodos de concentrador. Ejecutar el código antes y después de llamar a los métodos de concentrador es similar a cómo el middleware tiene la capacidad de ejecutar el código antes y después de una solicitud HTTP. Entre los usos habituales se incluyen el registro, el control de errores y la validación de argumentos.

Para más información, consulte Uso de filtros del concentrador en ASP.NETSignalR.

Invocaciones de concentrador paralelo de SignalR

SignalR de ASP.NET Core ahora es capaz de controlar las invocaciones del concentrador en paralelo. Se puede cambiar el comportamiento predeterminado para permitir que los clientes invoquen más de un método de concentrador a la vez:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSignalR(options =>
    {
        options.MaximumParallelInvocationsPerClient = 5;
    });
}

Se ha agregado compatibilidad con Messagepack en el cliente de Java SignalR.

Un nuevo paquete, com.microsoft.signalr.messagepack, agrega compatibilidad con MessagePack al cliente de Java SignalR. Para usar el protocolo del concentrador de MessagePack, agregue .withHubProtocol(new MessagePackHubProtocol()) al generador de conexiones:

HubConnection hubConnection = HubConnectionBuilder.create(
                           "http://localhost:53353/MyHub")
               .withHubProtocol(new MessagePackHubProtocol())
               .build();

Kestrel

  • Los puntos de conexión recargables mediante la configuración Kestrel puede detectar cambios en la configuración pasada a KestrelServerOptions.Configure y desenlace de los puntos de conexión existentes y enlace a nuevos puntos de conexión sin necesidad de reiniciar la aplicación cuando el parámetro reloadOnChange es true. De forma predeterminada, cuando se usa ConfigureWebHostDefaults o CreateDefaultBuilder, Kestrel se enlaza a la subsección de la configuración "Kestrel" con reloadOnChange habilitado. Las aplicaciones deben pasar reloadOnChange: true al llamar a KestrelServerOptions.Configure manualmente para obtener los puntos de conexión que se van a cargar.

  • Mejoras de los encabezados de respuesta HTTP/2 Para más información, consulte Mejoras de rendimiento en la sección siguiente.

  • Compatibilidad con tipos de puntos de conexión adicionales en el transporte de sockets: Al agregar a la nueva API introducida en System.Net.Sockets, el transporte predeterminado de sockets en Kestrel permite el enlace tanto a los identificadores de archivo existentes como a los sockets de dominio de Unix. La compatibilidad con el enlace a los identificadores de archivos existentes permite el uso de la integración de Systemd existente sin necesidad del transporte de libuv.

  • Descodificación de encabezado personalizada en Kestrel: Las aplicaciones pueden especificar qué propiedad Encoding se va a usar para interpretar los encabezados entrantes basándose en el nombre del encabezado en lugar de establecerse en UTF-8 de forma predeterminada. Establezca la propiedad Microsoft.AspNetCore.Server.Kestrel.KestrelServerOptions.RequestHeaderEncodingSelector para especificar la codificación que se va a usar:

    public static IHostBuilder CreateHostBuilder(string[] args) =>
      Host.CreateDefaultBuilder(args)
          .ConfigureWebHostDefaults(webBuilder =>
          {
              webBuilder.ConfigureKestrel(options =>
              {
                  options.RequestHeaderEncodingSelector = encoding =>
                  {
                        return encoding switch
                        {
                            "Host" => System.Text.Encoding.Latin1,
                            _ => System.Text.Encoding.UTF8,
                        };
                  };
              });
              webBuilder.UseStartup<Startup>();
          });
    

Opciones específicas del punto de conexión de Kestrel mediante configuración

Se ha agregado compatibilidad con la configuración de las opciones específicas del punto de conexión de Kestrel mediante configuración. Las configuraciones específicas del punto de conexión incluyen:

  • Protocolos HTTP usados
  • Protocolos TLS
  • Certificado seleccionado
  • Modo de certificado de cliente

La configuración permite especificar qué certificado se selecciona en función del nombre de servidor especificado. El nombre del servidor forma parte de la extensión de Indicación de nombre de servidor (SNI) al protocolo TLS, como indica el cliente. La configuración de Kestrel también admite un prefijo de carácter comodín en el nombre de host.

En el ejemplo siguiente se muestra cómo especificar un punto de conexión específico mediante un archivo de configuración:

{
  "Kestrel": {
    "Endpoints": {
      "EndpointName": {
        "Url": "https://*",
        "Sni": {
          "a.example.org": {
            "Protocols": "Http1AndHttp2",
            "SslProtocols": [ "Tls11", "Tls12"],
            "Certificate": {
              "Path": "testCert.pfx",
              "Password": "testPassword"
            },
            "ClientCertificateMode" : "NoCertificate"
          },
          "*.example.org": {
            "Certificate": {
              "Path": "testCert2.pfx",
              "Password": "testPassword"
            }
          },
          "*": {
            // At least one sub-property needs to exist per
            // SNI section or it cannot be discovered via
            // IConfiguration
            "Protocols": "Http1",
          }
        }
      }
    }
  }
}

Indicación de nombre de servidor (SNI) es una extensión de TLS para incluir un dominio virtual como parte de la negociación SSL. Lo que esto significa efectivamente es que el nombre de dominio virtual, o un nombre de host, puede utilizarse para identificar el punto de conexión de la red.

Mejoras en el rendimiento

HTTP/2

  • Reducciones significativas en las asignaciones en la ruta de acceso del código HTTP/2.

  • Compatibilidad con la compresión dinámica HPack de encabezados de respuesta HTTP/2 en Kestrel. Para más información, consulte Tamaño de tabla de encabezado y HPACK: la característica silenciosa de HTTP/2.

  • Envío de tramas PING HTTP/2: HTTP/2 tiene un mecanismo para enviar tramas de PING para asegurarse de que sigue siendo funcional una conexión inactiva. Asegurarse de que una conexión viable es especialmente útil cuando se trabaja con flujos de larga duración que suelen estar inactivos, pero solo se ven de forma intermitente las actividades, por ejemplo, las secuencias de gRPC. Las aplicaciones pueden enviar tramas de PING periódicas en Kestrel estableciendo límites en KestrelServerOptions:

    public static IHostBuilder CreateHostBuilder(string[] args) =>
      Host.CreateDefaultBuilder(args)
          .ConfigureWebHostDefaults(webBuilder =>
          {
              webBuilder.ConfigureKestrel(options =>
              {
                  options.Limits.Http2.KeepAlivePingInterval =
                                                 TimeSpan.FromSeconds(10);
                  options.Limits.Http2.KeepAlivePingTimeout =
                                                 TimeSpan.FromSeconds(1);
              });
              webBuilder.UseStartup<Startup>();
          });
    

Contenedores

Antes de .NET 5.0, la creación y publicación de un Dockerfile para una aplicación ASP.NET Core necesitaba extraer toda la SDK de .NET Core y la imagen de ASP.NET Core. Con esta versión, se reduce el número de bytes de las imágenes del SDK y los bytes extraídos para la imagen de ASP.NET Core se eliminan en gran medida. Para más información, consulte este comentario de un problema de GitHub.

Autenticación y autorización

Autenticación de Id. de Microsoft Entra con Microsoft.Identity. Web

Las plantillas de proyecto ASP.NET Core ahora se integran con Microsoft.Identity.Web para gestionar la autenticación con Microsoft Entra ID. El paquete Microsoft.Identity.Web proporciona:

  • Una mejor experiencia para la autenticación a través de Microsoft Entra ID.
  • Una manera más sencilla de acceder a los recursos de Azure en nombre de los usuarios, incluido Microsoft Graph. Consulte el ejemplo Microsoft.Identity.Web, que comienza con un inicio de sesión básico y avanza a través de varios inquilinos, mediante el uso de las API de Azure, el uso de Microsoft Graph y la protección de sus propias API. Microsoft.Identity.Web está disponible junto con .NET 5.

Acceso anónimo permitido a un punto de conexión

El método de extensión AllowAnonymous permite el acceso anónimo a un punto de conexión:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        })
        .AllowAnonymous();
    });
}

Control personalizado de errores de autorización

El control personalizado de los errores de autorización es ahora más fácil con la nueva interfaz IAuthorizationMiddlewareResultHandler invocada por el middleware de autorización. La implementación predeterminada sigue siendo la misma, pero se puede registrar un controlador personalizado en [inserción de dependencias, que permite respuestas HTTP personalizadas basadas en el motivo del error de la autorización. Consulte este ejemplo que muestra el uso de la IAuthorizationMiddlewareResultHandler.

Autorización al usar el enrutamiento de punto de conexión

La autorización al usar el enrutamiento del punto de conexión ahora recibe HttpContext en lugar de la instancia del punto de conexión. Esto permite que el middleware de autorización tenga acceso a RouteData y otras propiedades de HttpContext a las que no se pudo tener acceso a través de la clase Endpoint. El punto de conexión se puede capturar desde el contexto mediante context.GetEndpoint.

Control de acceso basado en roles con autenticación Kerberos y LDAP en Linux

Consulte Autenticación Kerberos y control de acceso basado en rol (RBAC)

Mejoras en la API

Métodos de extensión JSON para HttpRequest y HttpResponse

Los datos JSON se pueden leer y escribir desde un HttpRequest y HttpResponse mediante los nuevos métodos de extensión ReadFromJsonAsync y WriteAsJsonAsync. Estos métodos de extensión utilizan el serializador System.Text.JSON para controlar los datos JSON. El nuevo método de extensión de HasJsonContentType también puede comprobar si una solicitud tiene un tipo de contenido JSON.

Los métodos de extensión JSON se pueden combinar con el enrutamiento de punto de conexión para crear las API JSON en un estilo de programación que llamamos ruta al código. Es una opción nueva para los desarrolladores que desean crear las API JSON básicas de una manera ligera. Por ejemplo, una aplicación web que tiene solo unos cuantos puntos de conexión puede optar por usar la ruta al código en lugar de la funcionalidad completa de ASP.NET Core MVC:

endpoints.MapGet("/weather/{city:alpha}", async context =>
{
    var city = (string)context.Request.RouteValues["city"];
    var weather = GetFromDatabase(city);

    await context.Response.WriteAsJsonAsync(weather);
});

System.Diagnostics.Activity

El formato predeterminado de System.Diagnostics.Activity ahora tiene como valor predeterminado el formato W3C. Esto hace que la compatibilidad con la traza distribuida en ASP.NET Core interoperable con más marcos de trabajo de forma predeterminada.

FromBodyAttribute

FromBodyAttribute ahora admite la configuración de una opción que permite que estos parámetros o propiedades se consideren opcionales:

public IActionResult Post([FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)]
                          MyModel model)
{
    ...
}

Otras mejoras

Hemos empezado a aplicar las anotaciones que aceptan valores NULL a ensamblados ASP.NET Core. Tenemos previsto anotar la mayor parte de la superficie común de la API pública de .NET 5 Framework.

Control de la activación de la clase de inicio

Se ha agregado una sobrecarga de UseStartup adicional que permite que una aplicación proporcione un Factory Method para controlar la activación de la clase Startup. El control de la activación de la clase Startup es útil para pasar parámetros adicionales a Startup que se inicializan junto con el host:

public class Program
{
    public static async Task Main(string[] args)
    {
        var logger = CreateLogger();
        var host = Host.CreateDefaultBuilder()
            .ConfigureWebHost(builder =>
            {
                builder.UseStartup(context => new Startup(logger));
            })
            .Build();

        await host.RunAsync();
    }
}

Actualización automática con dotnet watch

En .NET 5, la ejecución de dotnet watch en un proyecto de ASP.NET Core inicia el explorador predeterminado y actualiza automáticamente el explorador a medida que se realizan cambios en el código. Esto significa que puede:

  • Abrir un proyecto de ASP.NET Core en un editor de texto.
  • Ejecute dotnet watch.
  • Céntrese en los cambios de código mientras las herramientas controlan la reconstrucción, el reinicio y la recarga de la aplicación.

Formateador del registrador de consola

Se han realizado mejoras en el proveedor de registro de la consola en la biblioteca Microsoft.Extensions.Logging. Los desarrolladores ahora pueden implementar un ConsoleFormatter personalizado para ejercer el control completo sobre el formato y el color de la salida de la consola. Las API de formateador permiten un formato enriquecido mediante la implementación de un subconjunto de las secuencias de escape VT-100. VT-100 es compatible con la mayoría de los terminales modernos. El registrador de consola puede analizar las secuencias de escape en los terminales no compatibles, lo que permite a los desarrolladores crear un solo formateador para todos los terminales.

Registrador de la consola JSON

Además de admitir los formateadores personalizados, también hemos agregado un formateador JSON integrado que emite registros de JSON estructurados en la consola. En el código siguiente se muestra cómo cambiar del registrador predeterminado a JSON:

public static IHostBuilder CreateHostBuilder(string[] args) =>
           Host.CreateDefaultBuilder(args)
  .ConfigureLogging(logging =>
  {
     logging.AddJsonConsole(options =>
     {
         options.JsonWriterOptions = new JsonWriterOptions()
         { Indented = true };
     });
  })
  .ConfigureWebHostDefaults(webBuilder =>
  {
    webBuilder.UseStartup<Startup>();
  });

Los mensajes de registro que se emiten a la consola tienen formato JSON:

{
  "EventId": 0,
  "LogLevel": "Information",
  "Category": "Microsoft.Hosting.Lifetime",
  "Message": "Now listening on: https://localhost:5001",
  "State": {
    "Message": "Now listening on: https://localhost:5001",
    "address": "https://localhost:5001",
    "{OriginalFormat}": "Now listening on: {address}"
  }
}