Novità di ASP.NET Core 5.0

Questo articolo illustra le modifiche più significative in ASP.NET Core 5.0 con collegamenti alla documentazione pertinente.

ASP.NET Core MVC e Razor miglioramenti

Associazione di modelli DateTime come UTC

L'associazione di modelli supporta ora l'associazione di stringhe di ora UTC a DateTime. Se la richiesta contiene una stringa di ora UTC, l'associazione di modelli lo associa a un'ora UTC DateTime. Ad esempio, la stringa di ora seguente è associata all'ora UTC DateTime: https://example.com/mycontroller/myaction?time=2019-06-14T02%3A30%3A04.0576719Z

Associazione di modelli e convalida con tipi di record C# 9

I tipi di record C# 9 possono essere usati con l'associazione di modelli in un controller MVC o in una Razor pagina. I tipi di record sono un buon modo per modellare i dati trasmessi in rete.

Di seguito PersonController , ad esempio, viene usato il tipo di record con l'associazione Person del modello e la convalida del modulo:

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

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

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

Ecco il file 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" />

Miglioramenti a DynamicRouteValueTransformer

ASP.NET Core 3.1 introdotto DynamicRouteValueTransformer come modo per usare l'endpoint personalizzato per selezionare dinamicamente un'azione del controller MVC o una Razor pagina. ASP.NET app Core 5.0 possono passare lo stato a un DynamicRouteValueTransformer oggetto e filtrare il set di endpoint scelti.

Varie

  • L'attributo [Compare] può essere applicato alle proprietà di un Razor modello Page.
  • I parametri e le proprietà associati dal corpo vengono considerati obbligatori per impostazione predefinita.

API Web

Specifica OpenAPI attivata per impostazione predefinita

La specifica OpenAPI è uno standard di settore per descrivere le API HTTP e integrarle in processi aziendali complessi o con terze parti. OpenAPI è ampiamente supportato da tutti i provider di servizi cloud e da molti registri API. Le app che generano documenti OpenAPI dalle API Web hanno un'ampia gamma di nuove opportunità in cui è possibile usare tali API. In collaborazione con i gestori del progetto open source Swashbuckle.AspNetCore, il modello di API ASP.NET Core contiene una dipendenza NuGet da Swashbuckle. Swashbuckle è un popolare pacchetto NuGet open source che genera documenti OpenAPI in modo dinamico. Swashbuckle esegue questa operazione introspettando i controller API e generando il documento OpenAPI in fase di esecuzione o in fase di compilazione usando l'interfaccia della riga di comando di Swashbuckle.

In ASP.NET Core 5.0, i modelli di API Web abilitano il supporto OpenAPI per impostazione predefinita. Per disabilitare OpenAPI:

  • Dalla riga di comando:

      dotnet new webapi --no-openapi true
    
  • Da Visual Studio: deselezionare Abilita supporto OpenAPI.

Tutti i file creati per i .csproj progetti API Web contengono il riferimento al pacchetto NuGet Swashbuckle.AspNetCore .

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

Il codice generato dal modello contiene codice in Startup.ConfigureServices che attiva la generazione di documenti OpenAPI:

public void ConfigureServices(IServiceCollection services)
{

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

Il Startup.Configure metodo aggiunge il middleware Swashbuckle, che abilita:

  • Processo di generazione di documenti.
  • Pagina dell'interfaccia utente di Swagger per impostazione predefinita in modalità di sviluppo.

Il codice generato dal modello non espone accidentalmente la descrizione dell'API durante la pubblicazione nell'ambiente di produzione.

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

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseAuthorization();

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

Importazione Gestione API di Azure

Quando ASP.NET progetti API di base abilitano OpenAPI, la pubblicazione di Visual Studio 2019 versione 16.8 e successive offre automaticamente un passaggio aggiuntivo nel flusso di pubblicazione. Gli sviluppatori che usano Azure Gestione API hanno la possibilità di importare automaticamente le API in Azure Gestione API durante il flusso di pubblicazione:

Azure API Management Import VS publishing

Esperienza di avvio migliore per i progetti API Web

Con OpenAPI abilitato per impostazione predefinita, l'esperienza di avvio delle app (F5) per gli sviluppatori di API Web migliora significativamente. Con ASP.NET Core 5.0, il modello di API Web è preconfigurato per caricare la pagina dell'interfaccia utente di Swagger. La pagina dell'interfaccia utente di Swagger fornisce sia la documentazione aggiunta per l'API pubblicata che consente di testare le API con un solo clic.

swagger/index.html view

Blazor

Miglioramenti delle prestazioni

Per .NET 5 sono stati apportati miglioramenti significativi alle Blazor WebAssembly prestazioni di runtime con particolare attenzione al rendering complesso dell'interfaccia utente e JSalla serializzazione ON. Nei test delle prestazioni, Blazor WebAssembly in .NET 5 è da due a tre volte più veloce per la maggior parte degli scenari. Per altre informazioni, vedere ASP.NET Blog: aggiornamenti di ASP.NET Core in .NET 5 Release Candidate 1.

Isolamento CSS

Blazor supporta ora la definizione di stili CSS con ambito per un determinato componente. Gli stili CSS specifici del componente semplificano il motivo degli stili in un'app e per evitare effetti collaterali involontari degli stili globali. Per altre informazioni, vedere isolamento CSS di ASP.NET CoreBlazor.

Nuovo InputFile componente

Il InputFile componente consente di leggere uno o più file selezionati da un utente per il caricamento. Per altre informazioni, vedere ASP.NET caricamenti di file coreBlazor.

Nuovi InputRadio componenti e InputRadioGroup

Blazorinclude componenti e InputRadioGroup predefiniti InputRadio che semplificano il data binding ai gruppi di pulsanti di opzione con la convalida integrata. Per altre informazioni, vedere ASP.NET Componenti di input coreBlazor.

Virtualizzazione di componenti

Migliorare le prestazioni percepite del rendering dei componenti usando il Blazor supporto virtualizzazione predefinito del framework. Per altre informazioni, vedere ASP.NET Virtualizzazione dei componenti coreRazor.

ontoggle supporto per eventi

Blazor gli eventi ora supportano l'evento ontoggle DOM. Per altre informazioni, vedere ASP.NET Gestione degli eventi CoreBlazor.

Impostare lo stato attivo dell'interfaccia utente nelle Blazor app

Usare il FocusAsync metodo pratico sui riferimenti agli elementi per impostare lo stato attivo dell'interfaccia utente su tale elemento. Per altre informazioni, vedere ASP.NET Gestione degli eventi CoreBlazor.

Attributi della classe CSS di convalida personalizzata

Gli attributi della classe CSS di convalida personalizzati sono utili quando si esegue l'integrazione con framework CSS, ad esempio Bootstrap. Per altre informazioni, vedere ASP.NET Convalida dei moduli principaliBlazor.

Supporto IAsyncDisposable

Razor i componenti supportano ora l'interfaccia IAsyncDisposable per la versione asincrona delle risorse allocate.

Riferimenti a oggetti e isolamento JavaScript

Blazorabilita l'isolamento JavaScript nei moduli JavaScript standard. Per altre informazioni, vedere Chiamare funzioni JavaScript da metodi .NET in ASP.NET Core Blazor.

I componenti del modulo supportano il nome visualizzato

I componenti predefiniti seguenti supportano i nomi visualizzati con il DisplayName parametro :

  • InputDate
  • InputNumber
  • InputSelect

Per altre informazioni, vedere ASP.NET Panoramica dei moduli principaliBlazor.

Parametri di route catch-all

I parametri di route catch-all, che acquisiscono i percorsi attraverso più limiti di cartella, sono supportati nei componenti. Per altre informazioni, vedere ASP.NET routing e navigazione coreBlazor.

Miglioramenti apportati al debug

Il debug delle Blazor WebAssembly app è stato migliorato in ASP.NET Core 5.0. Inoltre, il debug è ora supportato nelle Visual Studio per Mac. Per altre informazioni, vedere Eseguire il debug di app ASP.NET CoreBlazor.

Microsoft Identity v2.0 e MSAL v2.0

Blazor security ora usa Microsoft Identity v2.0 (Microsoft.Identity.Web e Microsoft.Identity.Web.UI) e MSAL v2.0. Per altre informazioni, vedere gli argomenti nel Blazor nodo Sicurezza e .Identity

Archiviazione browser protetto perBlazor Server

Blazor Server Le app possono ora usare il supporto predefinito per archiviare lo stato dell'app nel browser protetto da manomissioni usando ASP.NET protezione dei dati di base. I dati possono essere archiviati nell'archiviazione del browser locale o nell'archiviazione di sessione. Per altre informazioni, vedere ASP.NET Gestione dello stato coreBlazor.

Blazor WebAssembly prerendering

L'integrazione dei componenti è stata migliorata tra i modelli di hosting e Blazor WebAssembly le app possono ora pre-eseguire il pre-esecuzione dell'output nel server.

Miglioramenti di taglio/collegamento

Blazor WebAssembly esegue il trimming/collegamento del linguaggio intermedio durante una compilazione per ridurre il carico interno non necessario dagli assembly di output dell'app. Con il rilascio di ASP.NET Core 5.0, Blazor WebAssembly esegue un taglio migliorato con opzioni di configurazione aggiuntive. Per altre informazioni, vedere Configurare trimmer per ASP.NET opzioni Core Blazor e Trimming.

Analizzatore compatibilità browser

Blazor WebAssembly Le app hanno come destinazione l'area di attacco completa dell'API .NET, ma non tutte le API .NET sono supportate in WebAssembly a causa di vincoli sandbox del browser. Le API non supportate generano un'eccezione PlatformNotSupportedException durante l'esecuzione in WebAssembly. Un analizzatore di compatibilità della piattaforma avvisa lo sviluppatore quando l'app usa API non supportate dalle piattaforme di destinazione dell'app. Per altre informazioni, vedere Utilizzare i componenti ASP.NET Core Razor di una libreria di classi Razor (RCL).

Assembly di caricamento differita

Blazor WebAssembly Le prestazioni di avvio dell'app possono essere migliorate rinviando il caricamento di alcuni assembly dell'applicazione fino a quando non sono necessari. Per altre informazioni, vedere Assembly di caricamento differita in ASP.NET Core Blazor WebAssembly.

Supporto aggiornato per la globalizzazione

Il supporto per la globalizzazione è disponibile in Blazor WebAssembly base ai componenti internazionali per Unicode (ICU). Per altre informazioni, vedere ASP.NET Globalizzazione e localizzazione di coreBlazor.

gRPC

Molti miglioramenti della preformance sono stati apportati in gRPC. Per altre informazioni, vedere Miglioramenti delle prestazioni di gRPC in .NET 5.

Per altre informazioni su gRPC, vedere Panoramica di gRPC in .NET.

SignalR

SignalR Filtri hub

SignalR I filtri hub, denominati pipeline hub in ASP.NET SignalR, è una funzionalità che consente l'esecuzione del codice prima e dopo la chiamata dei metodi hub. L'esecuzione di codice prima e dopo la chiamata dei metodi hub è simile alla modalità con cui il middleware ha la possibilità di eseguire il codice prima e dopo una richiesta HTTP. Gli usi comuni includono la registrazione, la gestione degli errori e la convalida degli argomenti.

Per altre informazioni, vedere Usare i filtri hub in ASP.NET Core SignalR.

SignalR chiamate all'hub parallelo

ASP.NET Core SignalR è ora in grado di gestire le chiamate dell'hub parallelo. Il comportamento predefinito può essere modificato per consentire ai client di richiamare più di un metodo hub alla volta:

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

Aggiunta del supporto messagepack nel SignalR client Java

Un nuovo pacchetto, com.microsoft.signalr.messagepack, aggiunge il supporto messagePack al SignalR client Java. Per usare il protocollo hub MessagePack, aggiungere .withHubProtocol(new MessagePackHubProtocol()) al generatore di connessioni:

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

Kestrel

  • Endpoint ricaricabili tramite la configurazione: Kestrel può rilevare le modifiche alla configurazione passate a KestrelServerOptions.Configure e unbind da endpoint esistenti e associarsi a nuovi endpoint senza richiedere un riavvio dell'applicazione quando il reloadOnChange parametro è true. Per impostazione predefinita, quando si usa ConfigureWebHostDefaults o CreateDefaultBuilder, Kestrel viene associato alla sottosezione di configurazione "Kestrel" con reloadOnChange abilitata. Le app devono passare reloadOnChange: true quando si chiama KestrelServerOptions.Configure manualmente per ottenere endpoint ricaricabili.

  • Miglioramenti delle intestazioni di risposta HTTP/2. Per altre informazioni, vedere Miglioramenti delle prestazioni nella sezione successiva.

  • Supporto per altri tipi di endpoint nel trasporto dei socket: l'aggiunta alla nuova API introdotta in System.Net.Sockets, il trasporto predefinito dei socket in Kestrel consente l'associazione a handle di file esistenti e socket di dominio Unix. Il supporto per l'associazione a handle di file esistenti consente di usare l'integrazione esistente Systemd senza richiedere il libuv trasporto.

  • Decodifica dell'intestazione personalizzata in Kestrel: le app possono specificare quale Encoding usare per interpretare le intestazioni in ingresso in base al nome dell'intestazione anziché impostare per impostazione predefinita UTF-8. Impostare la Microsoft.AspNetCore.Server.Kestrel.KestrelServerOptions.RequestHeaderEncodingSelector proprietà per specificare la codifica da usare:

    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>();
          });
    

Kestrel opzioni specifiche dell'endpoint tramite la configurazione

È stato aggiunto il supporto per la configurazione delle Kestrelopzioni specifiche dell'endpoint tramite la configurazione. Le configurazioni specifiche dell'endpoint includono:

  • Protocolli HTTP usati
  • Protocolli TLS usati
  • Certificato selezionato
  • Modalità certificato client

La configurazione consente di specificare il certificato selezionato in base al nome del server specificato. Il nome del server fa parte dell'estensione SNI (Server Name Indication) al protocollo TLS, come indicato dal client. KestrelLa configurazione di supporta anche un prefisso con caratteri jolly nel nome host.

L'esempio seguente illustra come specificare un file di configurazione specifico dell'endpoint:

{
  "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",
          }
        }
      }
    }
  }
}

L'indicazione del nome del server (SNI) è un'estensione TLS per includere un dominio virtuale come parte della negoziazione SSL. Ciò significa in modo efficace che il nome di dominio virtuale, o un nome host, può essere usato per identificare l'endpoint di rete.

Miglioramenti delle prestazioni

HTTP/2

  • Riduzioni significative delle allocazioni nel percorso del codice HTTP/2.

  • Supporto per la compressione dinamica HPack delle intestazioni di risposta HTTP/2 in Kestrel. Per altre informazioni, vedere Dimensioni della tabella di intestazione e HPACK: il killer invisibile all'utente (funzionalità) di HTTP/2.

  • Invio di frame PING HTTP/2: HTTP/2 ha un meccanismo per l'invio di frame PING per garantire che una connessione inattiva sia ancora funzionante. Garantire una connessione valida è particolarmente utile quando si usano flussi di lunga durata che sono spesso inattivi, ma visualizzano solo in modo intermittente attività, ad esempio flussi gRPC. Le app possono inviare frame PING periodici in Kestrel impostando limiti su 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>();
          });
    

Contenitori

Prima di .NET 5.0, la compilazione e la pubblicazione di un Dockerfile per un'app ASP.NET Core richiedevano il pull dell'intero SDK .NET Core e dell'immagine ASP.NET Core. Con questa versione, il pull dei byte delle immagini SDK è ridotto e i byte estratti per l'immagine ASP.NET Core vengono eliminati in gran parte. Per altre informazioni, vedere questo commento sul problema di GitHub.

Autenticazione e autorizzazione

Autenticazione con MICROSOFT ENTRA ID con Microsoft.Identity. Web

I modelli di progetto ASP.NET Core ora si integrano con Microsoft.Identity.Web per gestire l'autenticazione con Microsoft Entra ID. Microsoft .Identity. Il pacchetto Web fornisce:

  • Un'esperienza migliore per l'autenticazione tramite Microsoft Entra ID.
  • Un modo più semplice per accedere alle risorse di Azure per conto degli utenti, incluso Microsoft Graph. Vedere Microsoft .Identity. Esempio Web, che inizia con un account di accesso di base e passa attraverso la multi-tenancy, usando le API di Azure, usando Microsoft Graph e proteggendo le proprie API. Microsoft.Identity.Web è disponibile insieme a .NET 5.

Consentire l'accesso anonimo a un endpoint

Il AllowAnonymous metodo di estensione consente l'accesso anonimo a un endpoint:

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();
    });
}

Gestione personalizzata degli errori di autorizzazione

La gestione personalizzata degli errori di autorizzazione è ora più semplice con la nuova interfaccia IAuthorizationMiddlewareResultHandler richiamata dal middleware di autorizzazione. L'implementazione predefinita rimane invariata, ma un gestore personalizzato può essere registrato in [Inserimento delle dipendenze, che consente risposte HTTP personalizzate in base al motivo per cui l'autorizzazione non è riuscita. Vedere questo esempio che illustra l'utilizzo IAuthorizationMiddlewareResultHandlerdi .

Autorizzazione quando si usa il routing degli endpoint

L'autorizzazione quando si usa il routing degli endpoint riceve ora anziché l'istanza HttpContext dell'endpoint. In questo modo il middleware di autorizzazione può accedere RouteData alle proprietà e ad altre proprietà di HttpContext che non erano accessibili tramite la Endpoint classe . L'endpoint può essere recuperato dal contesto usando il contesto. GetEndpoint.

Controllo degli accessi in base al ruolo con autenticazione Kerberos e LDAP in Linux

Vedere Autenticazione Kerberos e controllo degli accessi in base al ruolo

Miglioramenti delle API

JSMetodi di estensione ON per HttpRequest e HttpResponse

JSI dati ON possono essere letti e scritti da un oggetto HttpRequest e HttpResponse usando i metodi di estensione e WriteAsJsonAsync nuoviReadFromJsonAsync. Questi metodi di estensione usano il serializzatore System.Text.Json per gestire i JSdati ON. Il nuovo HasJsonContentType metodo di estensione può anche verificare se una richiesta ha un JStipo di contenuto ON.

I JSmetodi di estensione ON possono essere combinati con il routing degli endpoint per creare JSAPI ON in uno stile di programmazione che chiamiamo route al codice. Si tratta di una nuova opzione per gli sviluppatori che vogliono creare API ON di base JSin modo leggero. Ad esempio, un'app Web con solo pochi endpoint potrebbe scegliere di usare il routing al codice anziché la funzionalità completa di 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

Il formato predefinito per System.Diagnostics.Activity ora è il formato W3C. In questo modo il supporto della traccia distribuita in ASP.NET Core interoperabilità con più framework per impostazione predefinita.

FromBodyAttribute

FromBodyAttribute supporta ora la configurazione di un'opzione che consente di considerare facoltativi questi parametri o proprietà:

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

Miglioramenti vari

È stata avviata l'applicazione di annotazioni nullable agli assembly ASP.NET Core. Si prevede di annotare la maggior parte della superficie dell'API pubblica comune del framework .NET 5.

Controllare l'attivazione della classe di avvio

È stato aggiunto un overload aggiuntivo UseStartup che consente a un'app di fornire un metodo factory per controllare l'attivazione della Startup classe. Il controllo dell'attivazione della Startup classe è utile per passare parametri aggiuntivi a che vengono inizializzati insieme all'host Startup :

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();
    }
}

Aggiornamento automatico con dotnet watch

In .NET 5, l'esecuzione di dotnet watch in un progetto ASP.NET Core avvia il browser predefinito e aggiorna automaticamente il browser man mano che vengono apportate modifiche al codice. Ciò significa che è possibile:

  • Aprire un progetto ASP.NET Core in un editor di testo.
  • Eseguire dotnet watch.
  • Concentrarsi sulle modifiche al codice mentre gli strumenti gestiscono la ricompilazione, il riavvio e il ricaricamento dell'app.

Formattatore logger della console

Sono stati apportati miglioramenti al provider di log della console nella Microsoft.Extensions.Logging libreria. Gli sviluppatori possono ora implementare un oggetto personalizzato ConsoleFormatter per esercitare il controllo completo sulla formattazione e la colorazione dell'output della console. Le API del formattatore consentono la formattazione avanzata implementando un subset delle sequenze di escape VT-100. VT-100 è supportato dalla maggior parte dei terminali moderni. Il logger della console può analizzare le sequenze di escape su terminali non supportati, consentendo agli sviluppatori di creare un unico formattatore per tutti i terminali.

JSON Console Logger

Oltre al supporto per i formattatori personalizzati, è stato aggiunto anche un formattatore ON predefinito JSche genera log ON strutturati JSnella console. Il codice seguente illustra come passare dal logger predefinito 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>();
  });

I messaggi di log generati nella console sono JSin formato ON:

{
  "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}"
  }
}