Hosting in-process con IIS e ASP.NET Core

L'hosting in-process esegue un'app ASP.NET Core nello stesso processo del processo di lavoro IIS. L'hosting in-process offre prestazioni migliori rispetto all'hosting out-of-process perché le richieste non vengono inserite in proxy sulla scheda di loopback, un'interfaccia di rete che restituisce il traffico di rete in uscita allo stesso computer.

Il diagramma seguente illustra la relazione tra IIS, il modulo ASP.NET Core e un'app ospitata in-process:

ASP.NET Core Module in the in-process hosting scenario

Abilitare l'hosting in-process

A partire da ASP.NET Core 3.0, l'hosting in-process è stato abilitato per impostazione predefinita per tutte le app distribuite in IIS.

Per configurare in modo esplicito un'app per l'hosting in-process, impostare il valore della <AspNetCoreHostingModel> proprietà su InProcess nel file di progetto (.csproj):

<PropertyGroup>
  <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>

Architettura generale

Il flusso generale di una richiesta è il seguente:

  1. Una richiesta arriva dal Web al driver HTTP.sys in modalità kernel.
  2. Il driver instrada la richiesta nativa IIS sulla porta configurata per il sito Web, in genere 80 (HTTP) o 443 (HTTPS).
  3. Il modulo ASP.NET Core riceve la richiesta nativa e la trasmette al server HTTP di IIS (IISHttpServer). Il server HTTP di IIS è un'implementazione di server in-process per IIS che converte la richiesta da nativa a gestita.

Dopo l'elaborazione della richiesta dal server HTTP IIS:

  1. La richiesta viene inviata alla pipeline middleware di ASP.NET Core.
  2. La pipeline middleware gestisce la richiesta e la passa come istanza di HttpContext alla logica dell'app.
  3. La risposta dell'app viene restituita a IIS tramite il server HTTP di IIS.
  4. IIS invia la risposta al client che ha avviato la richiesta.

CreateDefaultBuilder aggiunge un'istanza di IServer chiamando il metodo UseIIS per avviare CoreCLR e ospitare l'app all'interno del processo di lavoro IIS (w3wp.exe o iisexpress.exe). I test delle prestazioni indicano che l'hosting di un'app .NET Core in-process offre una velocità effettiva delle richieste significativamente superiore rispetto all'hosting dell'app out-of-process o all'inoltro delle richieste a Kestrel.

Le app pubblicate come un singolo file eseguibile non possono essere caricate dal modello di hosting in-process.

Configurazione dell'applicazione

Per configurare le opzioni di IIS includere una configurazione del servizio per IISServerOptions in Program.cs. Nell'esempio seguente viene disabilitato AutomaticAuthentication:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Server.IIS;
using Microsoft.EntityFrameworkCore;
using RPauth.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

builder.Services.Configure<IISServerOptions>(options =>
{
    options.AutomaticAuthentication = false;
});

builder.Services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
builder.Services.AddAuthentication(IISServerDefaults.AuthenticationScheme);

builder.Services.AddRazorPages();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

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

app.MapRazorPages();

app.Run();
Opzione Predefinita Impostazione
AutomaticAuthentication true Se true, IIS Server imposta l'utente HttpContext.User autenticato tramite l'autenticazione di Windows. Se false, il server fornisce solo un'identità per HttpContext.User e risponde alle richieste esplicite di AuthenticationScheme. Per il funzionamento di AutomaticAuthentication l’autenticazione di Windows deve essere abilitata in IIS. Per altre informazioni, vedere Autenticazione di Windows.
AuthenticationDisplayName null Imposta il nome visualizzato dagli utenti nelle pagine di accesso.
AllowSynchronousIO false Indica se l'I/O sincrono è consentito per HttpContext.Request e HttpContext.Response.
MaxRequestBodySize 30000000 Ottiene o imposta la dimensione massima del corpo della richiesta per HttpRequest. Notare che IIS stesso include il limite maxAllowedContentLength, che verrà elaborato prima del set MaxRequestBodySize in IISServerOptions. La modifica di MaxRequestBodySize non influisce su maxAllowedContentLength. Per aumentare maxAllowedContentLength, aggiungere una voce in web.config per impostare maxAllowedContentLength su un valore superiore. Per ulteriori informazioni, vedere Configurazione.

Differenze tra l'hosting in-process e out-of-process

In caso di hosting in-process, vengono applicate le caratteristiche seguenti:

  • Il server HTTP IIS (IISHttpServer) viene usato invece del Kestrel server. Per le chiamate UseIIS in-process CreateDefaultBuilder a:

    • Registrare IISHttpServer.
    • Configurare la porta e il percorso di base su cui il server deve eseguire l'ascolto in caso di esecuzione dietro il modulo ASP.NET Core.
    • Configurare l'host per l'acquisizione degli errori di avvio.
  • L'attributo requestTimeout non si applica all'hosting in-process.

  • Non è supportata la condivisione di un pool di app tra le app. Usare un pool di app per ogni app.

  • L'architettura, vale a dire il numero di bit dell'app, e il runtime installato (x64 o x86) devono corrispondere all'architettura del pool di app. Ad esempio, le app pubblicate per 32 bit (x86) devono avere abilitato 32 bit per i pool di applicazioni IIS. Per altre informazioni, vedere la sezione Creare il sito IIS.

  • Le disconnessioni del client vengono rilevate. Il HttpContext.RequestAborted token di annullamento viene annullato quando il client si disconnette.

  • In caso di hosting in-process, AuthenticateAsync non viene chiamato internamente per inizializzare un utente. Pertanto, un'implementazione di IClaimsTransformation usate per trasformare le attestazioni dopo ogni autenticazione non viene attivata per impostazione predefinita. Quando si trasformano le attestazioni con un'implementazione di IClaimsTransformation, chiamare AddAuthentication per aggiungere i servizi di autenticazione:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Server.IIS;
using Microsoft.EntityFrameworkCore;
using RPauth.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

builder.Services.Configure<IISServerOptions>(options =>
{
    options.AutomaticAuthentication = false;
});

builder.Services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
builder.Services.AddAuthentication(IISServerDefaults.AuthenticationScheme);

builder.Services.AddRazorPages();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

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

app.MapRazorPages();

app.Run();

L'hosting in-process esegue un'app ASP.NET Core nello stesso processo del processo di lavoro IIS. L'hosting in-process offre prestazioni migliori rispetto all'hosting out-of-process perché le richieste non vengono inserite in proxy sulla scheda di loopback, un'interfaccia di rete che restituisce il traffico di rete in uscita allo stesso computer.

Il diagramma seguente illustra la relazione tra IIS, il modulo ASP.NET Core e un'app ospitata in-process:

ASP.NET Core Module in the in-process hosting scenario

Abilitare l'hosting in-process

A partire da ASP.NET Core 3.0, l'hosting in-process è stato abilitato per impostazione predefinita per tutte le app distribuite in IIS.

Per configurare in modo esplicito un'app per l'hosting in-process, impostare il valore della <AspNetCoreHostingModel> proprietà su InProcess nel file di progetto (.csproj):

<PropertyGroup>
  <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>

Architettura generale

Il flusso generale di una richiesta è il seguente:

  1. Una richiesta arriva dal Web al driver HTTP.sys in modalità kernel.
  2. Il driver instrada la richiesta nativa IIS sulla porta configurata per il sito Web, in genere 80 (HTTP) o 443 (HTTPS).
  3. Il modulo ASP.NET Core riceve la richiesta nativa e la trasmette al server HTTP di IIS (IISHttpServer). Il server HTTP di IIS è un'implementazione di server in-process per IIS che converte la richiesta da nativa a gestita.

Dopo l'elaborazione della richiesta dal server HTTP IIS:

  1. La richiesta viene inviata alla pipeline middleware di ASP.NET Core.
  2. La pipeline middleware gestisce la richiesta e la passa come istanza di HttpContext alla logica dell'app.
  3. La risposta dell'app viene restituita a IIS tramite il server HTTP di IIS.
  4. IIS invia la risposta al client che ha avviato la richiesta.

CreateDefaultBuilder aggiunge un'istanza di IServer chiamando il metodo UseIIS per avviare CoreCLR e ospitare l'app all'interno del processo di lavoro IIS (w3wp.exe o iisexpress.exe). I test delle prestazioni indicano che l'hosting di un'app .NET Core in-process offre una velocità effettiva delle richieste significativamente superiore rispetto all'hosting dell'app out-of-process o all'inoltro delle richieste a Kestrel.

Le app pubblicate come un singolo file eseguibile non possono essere caricate dal modello di hosting in-process.

Configurazione dell'applicazione

Per configurare le opzioni di IIS includere una configurazione del servizio per IISServerOptions in ConfigureServices. L'esempio seguente disabilita AutomaticAuthentication:

services.Configure<IISServerOptions>(options => 
{
    options.AutomaticAuthentication = false;
});
Opzione Predefinita Impostazione
AutomaticAuthentication true Se true, IIS Server imposta l'utente HttpContext.User autenticato tramite l'autenticazione di Windows. Se false, il server fornisce solo un'identità per HttpContext.User e risponde alle richieste esplicite di AuthenticationScheme. Per il funzionamento di AutomaticAuthentication l’autenticazione di Windows deve essere abilitata in IIS. Per altre informazioni, vedere Autenticazione di Windows.
AuthenticationDisplayName null Imposta il nome visualizzato dagli utenti nelle pagine di accesso.
AllowSynchronousIO false Indica se l'I/O sincrono è consentito per HttpContext.Request e HttpContext.Response.
MaxRequestBodySize 30000000 Ottiene o imposta la dimensione massima del corpo della richiesta per HttpRequest. Notare che IIS stesso include il limite maxAllowedContentLength, che verrà elaborato prima del set MaxRequestBodySize in IISServerOptions. La modifica di MaxRequestBodySize non influisce su maxAllowedContentLength. Per aumentare maxAllowedContentLength, aggiungere una voce in web.config per impostare maxAllowedContentLength su un valore superiore. Per ulteriori informazioni, vedere Configurazione.

Differenze tra l'hosting in-process e out-of-process

In caso di hosting in-process, vengono applicate le caratteristiche seguenti:

  • Il server HTTP IIS (IISHttpServer) viene usato invece del Kestrel server. Per le chiamate UseIIS in-process CreateDefaultBuilder a:

    • Registrare IISHttpServer.
    • Configurare la porta e il percorso di base su cui il server deve eseguire l'ascolto in caso di esecuzione dietro il modulo ASP.NET Core.
    • Configurare l'host per l'acquisizione degli errori di avvio.
  • L'attributo requestTimeout non si applica all'hosting in-process.

  • Non è supportata la condivisione di un pool di app tra le app. Usare un pool di app per ogni app.

  • L'architettura, vale a dire il numero di bit dell'app, e il runtime installato (x64 o x86) devono corrispondere all'architettura del pool di app. Ad esempio, le app pubblicate per 32 bit (x86) devono avere abilitato 32 bit per i pool di applicazioni IIS. Per altre informazioni, vedere la sezione Creare il sito IIS.

  • Le disconnessioni del client vengono rilevate. Il HttpContext.RequestAborted token di annullamento viene annullato quando il client si disconnette.

  • In caso di hosting in-process, AuthenticateAsync non viene chiamato internamente per inizializzare un utente. Pertanto, un'implementazione di IClaimsTransformation usate per trasformare le attestazioni dopo ogni autenticazione non viene attivata per impostazione predefinita. Quando si trasformano le attestazioni con un'implementazione di IClaimsTransformation, chiamare AddAuthentication per aggiungere i servizi di autenticazione:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient<IClaimsTransformation, ClaimsTransformer>();
        services.AddAuthentication(IISServerDefaults.AuthenticationScheme);
    }
    
    public void Configure(IApplicationBuilder app)
    {
        app.UseAuthentication();
    }
    
  • Le distribuzioni di pacchetti Web (a file singolo) non sono supportate.