Condividi tramite


File statici in ASP.NET Core

Note

Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 10 di questo articolo.

Warning

Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere i criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 9 di questo articolo.

I file statici, detti anche asset statici, sono file di un'app ASP.NET Core che non vengono generate dinamicamente. Vengono invece serviti direttamente ai client su richiesta, ad esempio file HTML, CSS, image e JavaScript.

Per la guida Blazor sui file statici, che si aggiunge o sostituisce le linee guida in questo articolo, vedere ASP.NET Core Blazor file statici.

Per abilitare la gestione dei file statici in ASP.NET Core, chiamare MapStaticAssets.

Per impostazione predefinita, i file statici vengono archiviati all'interno della directory radice Web del progetto. La directory predefinita è {CONTENT ROOT}/wwwroot, dove il {CONTENT ROOT} segnaposto è la radice del contenuto dell'app. Solo i file nella cartella wwwroot saranno indirizzabili, quindi non è necessario preoccuparsi del resto del codice.

Solo i file con estensioni di file specifiche mappate ai tipi di supporto supportati vengono considerati come asset Web statici.

Gli asset Web statici vengono individuati in fase di compilazione e ottimizzati usando l'impronta digitale basata sul contenuto per impedire il riutilizzo dei file precedenti. Gli asset vengono compressi anche per ridurre i tempi di distribuzione degli asset.

In fase di esecuzione, gli asset Web statici individuati vengono esposti come endpoint con intestazioni HTTP applicate, ad esempio intestazioni di memorizzazione nella cache e intestazioni del tipo di contenuto. Un asset viene servito una volta fino a quando il file non cambia o il browser cancella la cache. Le intestazioni ETag, Last-Modified e Content-Type sono impostate. Il browser non può usare asset non aggiornati dopo l'aggiornamento di un'app.

La distribuzione di risorse statiche è basata sul routing degli endpoint, quindi è compatibile con altre funzionalità che supportano gli endpoint, come l'autorizzazione. È progettato per funzionare con tutti i framework dell'interfaccia utente, tra cui Blazor, Razor Pages e MVC.

Map Static Assets offre i vantaggi seguenti:

  • Compressione in fase di compilazione per tutti gli asset nell'app, inclusi JavaScript (JS) e fogli di stile, ma escludendo gli asset di immagine e carattere già compressi. La compressione Gzip (Content-Encoding: gz) viene usata durante lo sviluppo. La compressione Gzip e Brotli (Content-Encoding: br) vengono usate durante la pubblicazione.
  • Impronta digitale per tutti gli asset durante il processo di build con una stringa codificata Base64 dell'hash SHA-256 del contenuto di ogni file. Ciò impedisce di riutilizzare una versione precedente di un file, anche se il file precedente viene memorizzato nella cache. Gli asset con impronta digitale vengono memorizzati nella cache usando la immutable direttiva , che comporta che il browser non richieda mai più l'asset fino a quando non cambia. Per i browser che non supportano la immutable direttiva, viene aggiunta una max-age direttiva .
    • Anche se un asset non ha un'impronta digitale, i contenuti basati su ETags vengono generati per ogni asset statico usando l'hash dell'impronta digitale del file come valore ETag. In questo modo, il browser scarica un file solo se il contenuto cambia (o il file viene scaricato per la prima volta).
    • Internamente, il framework esegue il mapping degli asset fisici alle impronte digitali, che consente all'app di:
      • Trovare asset generati automaticamente, ad esempio Razor css con ambito componente per Blazorla funzionalità di isolamento CSS e JS gli asset descritti dalle JS mappe di importazione.
      • Generare tag di collegamento nel <head> contenuto della pagina per precaricare gli asset.

Mapping di asset statici non fornisce funzionalità per la minimizzazione o altre trasformazioni di file. La minificazione viene in genere gestita da codice personalizzato o strumenti di terze parti.

Per abilitare la gestione dei file statici in ASP.NET Core, chiamare UseStaticFiles.

Per impostazione predefinita, i file statici vengono archiviati all'interno della directory radice Web del progetto. La directory predefinita è {CONTENT ROOT}/wwwroot, dove il {CONTENT ROOT} segnaposto è la radice del contenuto dell'app. Solo i file nella cartella wwwroot saranno indirizzabili, quindi non è necessario preoccuparsi del resto del codice.

In fase di esecuzione, gli asset Web statici vengono restituiti da Middleware Static File quando vengono richiesti con modifiche agli asset e con le intestazioni del tipo di contenuto applicate. Le intestazioni ETag, Last-Modified e Content-Type sono impostate.

Il middleware dei file statici abilita la gestione dei file statici e viene usato da un'app quando UseStaticFiles viene chiamato nella pipeline di elaborazione delle richieste dell'app. I file vengono serviti dal percorso specificato in IWebHostEnvironment.WebRootPath o WebRootFileProvider, che per impostazione predefinita corrisponde alla cartella radice web, tipicamente wwwroot.

È anche possibile gestire asset Web statici da progetti e pacchetti a cui si fa riferimento.

Modificare la directory radice del Web

Usare il UseWebRoot metodo se si vuole modificare la radice Web. Per altre informazioni, vedere ASP.NET Panoramica dei concetti fondamentali di base.

Impedire la pubblicazione di file in wwwroot con l'elemento di <Content> progetto nel file di progetto. Nell'esempio seguente viene impedita la pubblicazione di contenuto in wwwroot/local e le relative sottodirectory:

<ItemGroup>
  <Content Update="wwwroot\local\**\*.*" CopyToPublishDirectory="Never" />
</ItemGroup>

Il metodo CreateBuilder imposta la radice del contenuto nella directory corrente:

var builder = WebApplication.CreateBuilder(args);

Il metodo CreateDefaultBuilder imposta la radice del contenuto nella directory corrente:

Host.CreateDefaultBuilder(args)

Nella pipeline di elaborazione delle richieste dopo la chiamata a UseHttpsRedirection, chiamare MapStaticAssets nella pipeline di elaborazione delle richieste dell'app per abilitare la gestione di file statici dalla radice Web dell'app:

app.MapStaticAssets();

Nella pipeline di elaborazione delle richieste dopo la chiamata a UseHttpsRedirection, chiamare UseStaticFiles nella pipeline di elaborazione delle richieste dell'app per abilitare la gestione di file statici dalla radice Web dell'app:

app.UseStaticFiles();

I file statici sono accessibili tramite un percorso relativo alla radice Web.

Per accedere a un'immagine all'indirizzo wwwroot/images/favicon.png:

  • Formato URL: https://{HOST}/images/{FILE NAME}
    • Il {HOST} segnaposto è l'host.
    • Il {FILE NAME} segnaposto è il nome del file.
  • Esempi
    • URL assoluto: https://localhost:5001/images/favicon.png
    • URL relativa alla radice: images/favicon.png

In un'app Blazor carica images/favicon.png l'immagine dell'icona (favicon.png) dalla cartella dell'app wwwroot/images :

<link rel="icon" type="image/png" href="images/favicon.png" />

Nelle app Pages e MVC, il carattere tilde Razor indica la radice del web ~. Nell'esempio seguente, ~/images/favicon.png carica l'immagine dell'icona (favicon.png) dalla cartella dell'app wwwroot/images :

<link rel="icon" type="image/png" href="~/images/favicon.png" />

Interrompi la pipeline dei middleware

Per evitare di eseguire la completa pipeline middleware dopo che un asset statico è stato corrisposto, che è il comportamento di UseStaticFiles, chiamare ShortCircuit su MapStaticAssets. La chiamata ShortCircuit immediata esegue l'endpoint e restituisce la risposta, impedendo l'esecuzione di altri middleware per le richieste di asset statici:

app.MapStaticAssets().ShortCircuit();

Controllare la memorizzazione nella cache dei file statici durante lo sviluppo

Quando si esegue nell'ambiente di sviluppo, ad esempio durante i test di sviluppo di Ricaricamento rapido di Visual Studio , il framework esegue l'override delle intestazioni della cache per impedire ai browser di memorizzare nella cache i file statici. Ciò consente di garantire che la versione più recente dei file venga usata quando i file cambiano, evitando problemi con il contenuto non aggiornato. Nell'ambiente di produzione vengono impostate le intestazioni della cache corrette, consentendo ai browser di memorizzare nella cache gli asset statici come previsto.

Per disabilitare questo comportamento, impostare su EnableStaticAssetsDevelopmentCachingtrue nel file di impostazione dell'app dell'ambiente di sviluppo (appsettings.Development.json).

File statici in ambienti nonDevelopment

Quando si esegue un'app in locale, gli asset Web statici sono abilitati solo nell'ambiente di sviluppo. Per abilitare i file statici per ambienti diversi da Sviluppo durante lo sviluppo locale e il test ,ad esempio nell'ambiente di gestione temporanea, chiamare UseStaticWebAssets su WebApplicationBuilder.

Warning

Chiamate UseStaticWebAssets per l'ambiente esatto in modo da prevenire l'attivazione della funzionalità in produzione, poiché i file vengono serviti da percorsi separati su disco diversi dal progetto. Nell'esempio riportato in questa sezione viene controllato l'ambiente di staging con IsStaging.

if (builder.Environment.IsStaging())
{
    builder.WebHost.UseStaticWebAssets();
}

Servire i file all'esterno della directory principale del web tramite IWebHostEnvironment.WebRootPath

Quando IWebHostEnvironment.WebRootPath è impostato su una cartella diversa da wwwroot, vengono visualizzati i comportamenti predefiniti seguenti:

  • Nell'ambiente di sviluppo, gli asset statici vengono serviti da wwwroot se gli asset con lo stesso nome si trovano sia wwwroot in che in una cartella diversa assegnata a WebRootPath.
  • In qualsiasi ambiente diverso dallo sviluppo, gli asset statici duplicati vengono serviti dalla WebRootPath cartella .

Si consideri un'app Web creata dal modello Web vuoto:

  • Contenente un file Index.html in wwwroot e wwwroot-custom.
  • Il Program file viene aggiornato per impostare WebRootPath = "wwwroot-custom".
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    WebRootPath = "wwwroot-custom"
});

Per impostazione predefinita, per le richieste a /:

  • Nell'ambiente di sviluppo, wwwroot/Index.html viene restituito.
  • In qualsiasi ambiente diverso da quello di sviluppo, wwwroot-custom/Index.html viene restituito .

Per assicurarsi che gli asset da wwwroot-custom vengano sempre restituiti, usare uno degli approcci seguenti:

  • Eliminare gli asset con nomi duplicati in wwwroot.

  • Impostare ASPNETCORE_ENVIRONMENT in Properties/launchSettings.json a qualsiasi valore diverso da Development.

  • Disabilitare gli asset Web statici impostando su <StaticWebAssetsEnabled>false nel file di progetto dell'app. AVVERTIMENTO: La disabilitazione degli asset Web statici disabilita leRazor librerie di classi.

  • Aggiungere il codice XML seguente al file di progetto:

    <ItemGroup>
      <Content Remove="wwwroot\**" />
    </ItemGroup>
    

Il codice seguente aggiorna WebRootPath a un valore non di sviluppo (Staging), garantendo che venga restituito contenuto duplicato da wwwroot-custom anziché wwwroot:

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    EnvironmentName = Environments.Staging,
    WebRootPath = "wwwroot-custom"
});

Middleware dei file statici

Il middleware per i file statici consente di servire file statici in scenari specifici di file statici, di solito in aggiunta alle convenzioni di routing degli endpoint degli asset statici (MapStaticAssets).

Il middleware dei file statici è incluso nell'elaborazione delle richieste quando UseStaticFiles viene chiamato nella pipeline di elaborazione delle richieste dell'applicazione, in genere dopo l'aggiunta delle convenzioni degli endpoint per gli asset statici (MapStaticAssets).

Le convenzioni degli endpoint delle mappe delle risorse statiche sono usate nelle app che puntano a .NET 9 o versione successiva. Il middleware dei file statici deve essere usato nelle app destinate alle versioni di .NET precedenti a .NET 9.

Il middleware dei file statici gestisce i file statici, ma non fornisce lo stesso livello di ottimizzazione delle convenzioni degli endpoint per l'assegnazione delle risorse statiche. Le funzionalità di compressione e impronta digitale al tempo di compilazione del componente Map Static Assets, inerenti agli endpoint, non sono disponibili se ci si affida solo al middleware dei file statici.

Le convenzioni degli endpoint sono ottimizzate per gestire gli asset di cui l'app ha conoscenza in fase di esecuzione. Se l'app gestisce gli asset da altre posizioni, ad esempio risorse disco o incorporate, è necessario usare il middleware dei file statici.

Le funzionalità seguenti descritte in questo articolo sono supportate con il middleware per i file statici, ma non con le convenzioni degli endpoint di Map Static Assets.

Servire i file all'esterno della directory principale del web tramite UseStaticFiles

Si consideri la gerarchia di directory seguente con file statici che si trovano all'esterno della radice Web dell'app in una cartella denominata ExtraStaticFiles:

  • wwwroot
    • css
    • images
    • js
  • ExtraStaticFiles
    • images
      • red-rose.jpg

Una richiesta può accedere a red-rose.jpg configurando una nuova istanza di Static File Middleware.

Namespace per l'API seguente:

using Microsoft.Extensions.FileProviders;

Nella pipeline di elaborazione delle richieste dopo la chiamata esistente a MapStaticAssets (.NET 9 o versione successiva) o UseStaticFiles (.NET 8 o versioni precedenti):

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles")),
    RequestPath = "/static-files"
});

Nel codice precedente la ExtraStaticFiles gerarchia di directory viene esposta pubblicamente tramite il static-files segmento URL. Una richiesta a https://{HOST}/StaticFiles/images/red-rose.jpg, dove il segnaposto {HOST} è l'host, serve il file red-rose.jpg.

I seguenti riferimenti markup di ExtraStaticFiles/images/red-rose.jpg:

<img src="static-files/images/red-rose.jpg" alt="A red rose" />

Per l'esempio precedente, la notazione tilde-slash è supportata nelle pagine e visualizzazioni MVC (Razor), non per i componenti nelle app src="~/StaticFiles/images/red-rose.jpg".

Gestire i file da più posizioni

Le indicazioni contenute in questa sezione si applicano alle Razor app Pages e MVC. Per indicazioni applicabili a Blazor Web Apps, vedere ASP.NET Core Blazor file statici.

Si consideri il markup seguente che visualizza un logo aziendale:

<img src="~/logo.png" asp-append-version="true" alt="Company logo">

Lo sviluppatore intende usare l'helper tag immagine per aggiungere una versione e gestire il file da un percorso personalizzato, una cartella denominata ExtraStaticFiles.

Nell'esempio seguente viene chiamato MapStaticAssets per gestire i file da wwwroot e UseStaticFiles per gestire i file da ExtraStaticFiles:

Nella pipeline di elaborazione delle richieste dopo la chiamata esistente a MapStaticAssets (.NET 9 o versione successiva) o UseStaticFiles (.NET 8 o versioni precedenti):

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles"))
});

Nell'esempio seguente viene chiamato UseStaticFiles due volte per gestire i file da wwwroot e ExtraStaticFiles.

Nella pipeline di elaborazione della richiesta dopo la chiamata esistente a UseStaticFiles:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles"))
});

Usando il codice precedente, viene visualizzato il ExtraStaticFiles/logo.png file . Tuttavia, l'helper tag immagine (AppendVersion) non viene applicato perché l'helper tag dipende da WebRootFileProvider, che non è stato aggiornato per includere la ExtraStaticFiles cartella.

Il codice seguente aggiorna WebRootFileProvider per includere la cartella ExtraStaticFiles utilizzando un CompositeFileProvider. In questo modo, il tag helper delle immagini può applicare una versione alle immagini nella cartella ExtraStaticFiles.

Spazio dei nomi per l'API seguente:

using Microsoft.Extensions.FileProviders;

Nella pipeline di elaborazione delle richieste prima della chiamata esistente a MapStaticAssets (.NET 9 o versione successiva) o UseStaticFiles (.NET 8 o versioni precedenti):

var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
    Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles"));

var compositeProvider = new CompositeFileProvider(webRootProvider, newPathProvider);

app.Environment.WebRootFileProvider = compositeProvider;

Per impostazione predefinita, UseStaticFiles e UseFileServer sono impostati al provider di file che punta a wwwroot. Altre istanze di UseStaticFiles e UseFileServer possono essere fornite con altri provider di file per gestire i file da altre posizioni. Per maggiori informazioni, vedere UseStaticFiles ancora necessario con UseFileServer per wwwroot (dotnet/AspNetCore.Docs #15578).

Impostare le intestazioni della risposta HTTP

Usare StaticFileOptions per impostare le intestazioni di risposta HTTP. Oltre a configurare il middleware dei file statici per gestire i file statici, il codice seguente imposta l'intestazioneCache-Control su 604.800 secondi (una settimana).

Namespace per l'API seguente:

using Microsoft.AspNetCore.Http;

Nella pipeline di elaborazione delle richieste dopo la chiamata esistente a MapStaticAssets (.NET 9 o versione successiva) o UseStaticFiles (.NET 8 o versioni precedenti):

app.UseStaticFiles(new StaticFileOptions
{
    OnPrepareResponse = ctx =>
    {
        ctx.Context.Response.Headers.Append(
            "Cache-Control", "public, max-age=604800");
    }
});

Raccolta di asset di grandi dimensioni

Quando si gestiscono raccolte di asset di grandi dimensioni, considerati circa 1.000 o più asset, è consigliabile usare un bundler per ridurre il numero finale di asset serviti dall'app o per combinare MapStaticAssets con UseStaticFiles.

MapStaticAssets carica rapidamente i metadati precomputati acquisiti durante il processo di build delle risorse per supportare la compressione, la memorizzazione nella cache e il fingerprinting. Queste funzionalità sono a costo di un maggiore utilizzo della memoria da parte dell'app. Per gli asset a cui si accede di frequente, in genere vale la pena i costi. Per gli asset a cui non si accede di frequente, il compromesso potrebbe non valere i costi.

Se non si usa la creazione di bundle, è consigliabile combinare MapStaticAssets con UseStaticFiles. Nell'esempio seguente viene illustrato l'approccio .

Nel file di progetto (.csproj), la StaticWebAssetEndpointExclusionPattern proprietà MSBuild viene usata per filtrare gli endpoint dal manifesto finale per MapStaticAssets. I file esclusi vengono gestiti da UseStaticFiles e non traggono vantaggio dalla compressione, dalla memorizzazione nella cache e dall'impronta digitale.

Quando si imposta il valore di StaticWebAssetEndpointExclusionPattern, mantenere $(StaticWebAssetEndpointExclusionPattern) per mantenere il modello di esclusione predefinito del framework. Aggiungere altri modelli in un elenco delimitato da punto e virgola.

Nell'esempio seguente, il modello di esclusione rimuove i file statici nella cartella lib/icons, che rappresenta un batch ipotetico di icone.

<StaticWebAssetEndpointExclusionPattern>
  $(StaticWebAssetEndpointExclusionPattern);lib/icons/**
</StaticWebAssetEndpointExclusionPattern>

Dopo l'elaborazione del middleware di reindirizzamento HTTPS (app.UseHttpsRedirection();) nel Program file:

app.UseStaticFiles();

app.UseAuthorization();

app.MapStaticAssets();

Autorizzazione dei file statici

Quando un'app adotta criteri di autorizzazione di fallback, l'autorizzazione è necessaria per tutte le richieste che non specificano in modo esplicito un criterio di autorizzazione, incluse le richieste di file statici dopo l'elaborazione delle richieste del middleware di autorizzazione. Consentire l'accesso anonimo ai file statici applicando AllowAnonymousAttribute al generatore di endpoint per i file statici.

app.MapStaticAssets().Add(endpointBuilder => 
    endpointBuilder.Metadata.Add(new AllowAnonymousAttribute()));

Quando un'app adotta criteri di autorizzazione di fallback, l'autorizzazione è necessaria per tutte le richieste che non specificano in modo esplicito un criterio di autorizzazione, incluse le richieste di file statici dopo l'elaborazione delle richieste del middleware di autorizzazione. I modelli di ASP.NET Core consentono l'accesso anonimo ai file statici chiamando prima il metodo UseStaticFiles e poi il metodo UseAuthorization. La maggior parte delle app segue questo modello. Quando il middleware dei file statici viene chiamato prima del middleware di autorizzazione:

  • Non vengono eseguiti controlli di autorizzazione sui file statici.
  • I file statici gestiti dal middleware dei file statici, ad esempio quelli radice Web (in genere, wwwroot), sono accessibili pubblicamente.

Per gestire i file statici in base all'autorizzazione:

Namespace per l'API seguente:

using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.FileProviders;

Registrazione del servizio:

builder.Services.AddAuthorization(options =>
{
    options.FallbackPolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
});

Nella pipeline di elaborazione della richiesta dopo la chiamata a UseAuthorization:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "SecureStaticFiles")),
    RequestPath = "/static-files"
});

Namespace per l'API seguente:

using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.FileProviders;

In Startup.ConfigureServices:

services.AddAuthorization(options =>
{
    options.FallbackPolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
});

In Startup.Configure dopo la chiamata a UseAuthorization:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.ContentRootPath, "SecureStaticFiles")),
    RequestPath = "/static-files"
});

Nel codice precedente, i criteri di autorizzazione di fallback richiedono utenti autenticati. Gli endpoint, ad esempio controller e Razor Pagine, che specificano i propri requisiti di autorizzazione non usano la policy di autorizzazione di fallback. Ad esempio, Razor Pagine, controller o metodi di azione con [AllowAnonymous] o [Authorize(PolicyName="MyPolicy")] usano l'attributo di autorizzazione applicato anziché la politica di autorizzazione di fallback.

RequireAuthenticatedUser aggiunge DenyAnonymousAuthorizationRequirement all'istanza corrente, che impone l'autenticazione dell'utente corrente.

Gli asset statici archiviati nella radice web dell'app sono accessibili pubblicamente perché il middleware predefinito per i file statici (UseStaticFiles) viene chiamato prima di UseAuthorization. Gli asset statici nella SecureStaticFiles cartella richiedono l'autenticazione.

Un approccio alternativo per gestire i file in base all'autorizzazione consiste nel:

  • Archiviare i file all'esterno della radice web e di qualsiasi directory accessibile al middleware dei file statici.
  • Gestire i file tramite un metodo di azione a cui viene applicata l'autorizzazione e restituire un FileResult oggetto .

Da una Razor pagina (Pages/BannerImage.cshtml.cs):

public class BannerImageModel : PageModel
{
    private readonly IWebHostEnvironment _env;

    public BannerImageModel(IWebHostEnvironment env) => _env = env;

    public PhysicalFileResult OnGet()
    {
        var filePath = Path.Combine(
            _env.ContentRootPath, "SecureStaticFiles", "images", "red-rose.jpg");

        return PhysicalFile(filePath, "image/jpeg");
    }
}

Da un controller (Controllers/HomeController.cs):

[Authorize]
public IActionResult BannerImage()
{
    var filePath = Path.Combine(
        _env.ContentRootPath, "SecureStaticFiles", "images", "red-rose.jpg");

    return PhysicalFile(filePath, "image/jpeg");
}

L'approccio precedente richiede una pagina o un endpoint per ogni file.

L'esempio di endpoint di route seguente restituisce i file per gli utenti autenticati.

Nel file Program:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AuthenticatedUsers", b => b.RequireAuthenticatedUser());
});

...

app.MapGet("/files/{fileName}", IResult (string fileName) => 
{
    var filePath = GetOrCreateFilePath(fileName);

    if (File.Exists(filePath))
    {
        return TypedResults.PhysicalFile(filePath, fileName);
    }

    return TypedResults.NotFound("No file found with the supplied file name");
})
.WithName("GetFileByName")
.RequireAuthorization("AuthenticatedUsers");

L'esempio di endpoint di route seguente esegue il caricamento dei file per gli utenti autenticati con ruolo amministratore ("admin").

Nel file Program:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AdminsOnly", b => b.RequireRole("admin"));
});

...

// IFormFile uses memory buffer for uploading. For handling large 
// files, use streaming instead. See the *File uploads* article
// in the ASP.NET Core documentation:
// https://learn.microsoft.com/aspnet/core/mvc/models/file-uploads
app.MapPost("/files", async (IFormFile file, LinkGenerator linker, 
    HttpContext context) =>
{
    // Don't rely on the value in 'file.FileName', as it's only metadata that can 
    // be manipulated by the end-user. Consider the 'Utilities.IsFileValid' method 
    // that takes an 'IFormFile' and validates its signature within the 
    // 'AllowedFileSignatures'.

    var fileSaveName = Guid.NewGuid().ToString("N") + 
        Path.GetExtension(file.FileName);
    await SaveFileWithCustomFileName(file, fileSaveName);

    context.Response.Headers.Append("Location", linker.GetPathByName(context, 
        "GetFileByName", new { fileName = fileSaveName}));

    return TypedResults.Ok("File Uploaded Successfully!");
})
.RequireAuthorization("AdminsOnly");

In Startup.ConfigureServices:

services.AddAuthorization(options =>
{
    options.AddPolicy("AuthenticatedUsers", b => b.RequireAuthenticatedUser());
});

In Startup.Configure:

app.MapGet("/files/{fileName}", IResult (string fileName) => 
{
    var filePath = GetOrCreateFilePath(fileName);

    if (File.Exists(filePath))
    {
        return TypedResults.PhysicalFile(filePath, fileName);
    }

    return TypedResults.NotFound("No file found with the supplied file name");
})
.WithName("GetFileByName")
.RequireAuthorization("AuthenticatedUsers");

Il codice seguente carica i file per gli utenti autenticati nel ruolo di amministratore ("admin").

In Startup.ConfigureServices:

services.AddAuthorization(options =>
{
    options.AddPolicy("AdminsOnly", b => b.RequireRole("admin"));
});

In Startup.Configure:

// IFormFile uses memory buffer for uploading. For handling large 
// files, use streaming instead. See the *File uploads* article
// in the ASP.NET Core documentation:
// https://learn.microsoft.com/aspnet/core/mvc/models/file-uploads
app.MapPost("/files", async (IFormFile file, LinkGenerator linker, 
    HttpContext context) =>
{
    // Don't rely on the value in 'file.FileName', as it's only metadata that can 
    // be manipulated by the end-user. Consider the 'Utilities.IsFileValid' method 
    // that takes an 'IFormFile' and validates its signature within the 
    // 'AllowedFileSignatures'.

    var fileSaveName = Guid.NewGuid().ToString("N") + 
        Path.GetExtension(file.FileName);
    await SaveFileWithCustomFileName(file, fileSaveName);

    context.Response.Headers.Append("Location", linker.GetPathByName(context, 
        "GetFileByName", new { fileName = fileSaveName}));

    return TypedResults.Ok("File Uploaded Successfully!");
})
.RequireAuthorization("AdminsOnly");

Esplorazione della directory

La navigazione delle directory consente di elencare le directory all'interno di quelle specificate.

L'esplorazione della directory è disabilitata per impostazione predefinita per motivi di sicurezza. Per altre informazioni, vedere Considerazioni sulla sicurezza per i file statici.

Abilitare l'esplorazione della directory con l'API seguente:

Nell'esempio seguente :

  • Una images cartella nella radice dell'app contiene immagini per la navigazione nella directory.
  • Il percorso della richiesta per esplorare le immagini è /DirectoryImages.
  • La chiamata UseStaticFiles e l'impostazione FileProvider di StaticFileOptions abilita la visualizzazione dei collegamenti del browser ai singoli file.

Namespace per l'API seguente:

using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;

Registrazione del servizio:

builder.Services.AddDirectoryBrowser();

Nella pipeline di elaborazione delle richieste dopo la chiamata esistente a MapStaticAssets (.NET 9 o versione successiva) o UseStaticFiles (.NET 8 o versioni precedenti):

var fileProvider = new PhysicalFileProvider(
    Path.Combine(builder.Environment.WebRootPath, "images"));
var requestPath = "/DirectoryImages";

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = fileProvider,
    RequestPath = requestPath
});

app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
    FileProvider = fileProvider,
    RequestPath = requestPath
});

Namespace per l'API seguente:

using Microsoft.Extensions.FileProviders;
using System.IO;

In Startup.ConfigureServices:

services.AddDirectoryBrowser();

In Startup.Configure dopo la chiamata esistente a UseStaticFiles:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.WebRootPath, "images")),
    RequestPath = "/DirectoryImages"
});

app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.WebRootPath, "images")),
    RequestPath = "/DirectoryImages"
});

Il codice precedente consente di esplorare la cartella della directory wwwroot/images utilizzando l'URL https://{HOST}/DirectoryImages, con collegamenti a ogni file e cartella, dove il segnaposto {HOST} rappresenta l'host.

AddDirectoryBrowser aggiunge i servizi richiesti dal middleware di esplorazione della directory, incluso HtmlEncoder. Questi servizi possono essere aggiunti da altre chiamate, ad esempio AddRazorPages, ma è consigliabile chiamare AddDirectoryBrowser per assicurarsi che i servizi vengano aggiunti.

Gestire i documenti predefiniti

L'impostazione di una pagina predefinita fornisce ai visitatori un punto di partenza in un sito. Per gestire un file predefinito da wwwroot senza richiedere all'URL della richiesta di includere il nome del file, chiamare il UseDefaultFiles metodo .

UseDefaultFiles è un rewriter URL che non serve il file. Nella pipeline di elaborazione delle richieste prima della chiamata esistente a MapStaticAssets (.NET 9 o versione successiva) o UseStaticFiles (.NET 8 o versioni precedenti):

app.UseDefaultFiles();

Con UseDefaultFiles, le richieste a una cartella in wwwroot vengono cercate:

  • default.htm
  • default.html
  • index.htm
  • index.html

Il primo file trovato dall'elenco viene fornito come se la richiesta includa il nome del file. L'URL del browser continua a riflettere l'URI richiesto.

Il codice seguente modifica il nome file predefinito in default-document.html:

var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("default-document.html");
app.UseDefaultFiles(options);

Combinare i file statici, i documenti predefiniti e l'esplorazione della directory

UseFileServer combina le funzionalità di UseStaticFiles, UseDefaultFilese facoltativamente UseDirectoryBrowser.

Nella pipeline di elaborazione delle richieste dopo la chiamata esistente a MapStaticAssets (.NET 9 o versione successiva) o UseStaticFiles (.NET 8 o versioni precedenti), chiamare UseFileServer per abilitare la gestione dei file statici e il file predefinito:

app.UseFileServer();

L'esplorazione della directory non è abilitata per l'esempio precedente.

Il codice seguente abilita la gestione di file statici, il file predefinito e l'esplorazione della directory.

Registrazione del servizio:

builder.Services.AddDirectoryBrowser();

Nella pipeline di elaborazione della richiesta dopo la chiamata esistente a UseStaticFiles:

app.UseFileServer(enableDirectoryBrowsing: true);

In Startup.ConfigureServices:

services.AddDirectoryBrowser();

In Startup.Configure dopo la chiamata esistente a UseStaticFiles:

app.UseFileServer(enableDirectoryBrowsing: true);

Per l'indirizzo host (/), UseFileServer restituisce il documento HTML predefinito prima della pagina predefinita Razor (Pages/Index.cshtml) o della visualizzazione MVC predefinita (Home/Index.cshtml).

Considera la seguente gerarchia di directory:

  • wwwroot
    • css
    • images
    • js
  • ExtraStaticFiles
    • images
      • logo.png
    • default.html

Il codice seguente abilita la gestione di file statici, il file predefinito e l'esplorazione della directory di ExtraStaticFiles.

Namespace per l'API seguente:

using Microsoft.Extensions.FileProviders;

Registrazione del servizio:

builder.Services.AddDirectoryBrowser();

Nella pipeline di elaborazione della richiesta dopo la chiamata esistente a UseStaticFiles:

app.UseFileServer(new FileServerOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles")),
    RequestPath = "/static-files",
    EnableDirectoryBrowsing = true
});

Namespace per l'API seguente:

using Microsoft.Extensions.FileProviders;
using System.IO;

In Startup.ConfigureServices:

services.AddDirectoryBrowser();

In Startup.Configure dopo la chiamata esistente a UseStaticFiles:

app.UseFileServer(new FileServerOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.ContentRootPath, "ExtraStaticFiles")),
    RequestPath = "/static-files",
    EnableDirectoryBrowsing = true
});

AddDirectoryBrowser deve essere chiamato quando il valore della EnableDirectoryBrowsing proprietà è true.

Utilizzando la gerarchia di file e il codice precedenti, gli URL si risolvono come illustrato nella tabella seguente (il segnaposto {HOST} è l'host).

URI File di risposta
https://{HOST}/static-files/images/logo.png ExtraStaticFiles/images/logo.png
https://{HOST}/static-files ExtraStaticFiles/default.html

Se nella directory ExtraStaticFiles non esiste alcun file con nome predefinito, https://{HOST}/static-files restituisce l'elenco della directory e consente di fare clic sui collegamenti, dove il segnaposto {HOST} è l'host.

UseDefaultFiles ed UseDirectoryBrowser eseguono un reindirizzamento lato client dall'URI di destinazione senza un finale / all'URI di destinazione con un finale /. Ad esempio, da https://{HOST}/static-files (senza finale /) a https://{HOST}/static-files/ (include un finale /). Gli URL relativi all'interno della ExtraStaticFiles directory non sono validi senza una barra finale (/) a meno che non venga usata l'opzione RedirectToAppendTrailingSlash di DefaultFilesOptions .

Mappare le estensioni di file ai tipi MIME

Note

Per indicazioni applicabili alle Blazor app, vedere file statici di ASP.NET CoreBlazor.

Usare FileExtensionContentTypeProvider.Mappings per aggiungere o modificare l'estensione di file ai mapping dei tipi di contenuto MIME. Nell'esempio seguente vengono mappate diverse estensioni di file ai tipi MIME noti. L'estensione .rtf viene sostituita e .mp4 viene rimossa:

using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;

...

// Set up custom content types - associating file extension to MIME type
var provider = new FileExtensionContentTypeProvider();
// Add new mappings
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";
// Replace an existing mapping
provider.Mappings[".rtf"] = "application/x-msdownload";
// Remove MP4 videos
provider.Mappings.Remove(".mp4");

app.UseStaticFiles(new StaticFileOptions
{
    ContentTypeProvider = provider
});

Quando sono disponibili diverse opzioni di file statiche da configurare, è possibile impostare in alternativa il provider usando StaticFileOptions:

var provider = new FileExtensionContentTypeProvider();

...

builder.Services.Configure<StaticFileOptions>(options =>
{
    options.ContentTypeProvider = provider;
});

app.UseStaticFiles();

In Startup.Configure:

using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
using System.IO;

...

// Set up custom content types - associating file extension to MIME type
var provider = new FileExtensionContentTypeProvider();
// Add new mappings
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";
// Replace an existing mapping
provider.Mappings[".rtf"] = "application/x-msdownload";
// Remove MP4 videos
provider.Mappings.Remove(".mp4");

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.WebRootPath, "images")),
    RequestPath = "/images",
    ContentTypeProvider = provider
});

app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.WebRootPath, "images")),
    RequestPath = "/images"
});

Per altre informazioni, vedere Tipi di contenuto MIME.

Tipi di contenuto non standard

Il middleware dei file statici comprende quasi 400 tipi di contenuto di file noti. Se l'utente richiede un file con un tipo di file sconosciuto, il middleware del file statico passa la richiesta al middleware successivo nella pipeline. Se nessun middleware gestisce la richiesta, viene restituita la risposta 404 Non trovato. Se è abilitata l'esplorazione directory, viene visualizzato un collegamento al file nell'elenco directory.

Il codice seguente abilita la gestione di tipi di contenuto sconosciuti ed esegue il rendering del file sconosciuto come immagine:

app.UseStaticFiles(new StaticFileOptions
{
    ServeUnknownFileTypes = true,
    DefaultContentType = "image/png"
});

Con il codice precedente, una richiesta per un file con un tipo di contenuto sconosciuto viene restituita come immagine.

Warning

L'abilitazione ServeUnknownFileTypes è un rischio per la sicurezza. È disabilitato per impostazione predefinita e ne è sconsigliato l'uso. Eseguire il mapping delle estensioni di file ai tipi MIME offre un'alternativa più sicura alla gestione dei file con estensioni non standard.

Fornire un manifesto di file statici personalizzato

Se staticAssetsManifestPath è null, IHostEnvironment.ApplicationName viene usato per individuare il manifesto. In alternativa, specificare un percorso completo al file di manifesto. Se viene usato un percorso relativo, il framework cerca il file in AppContext.BaseDirectory.

Considerazioni sulla sicurezza per i file statici

Warning

L'uso di UseDirectoryBrowser e UseStaticFiles può comportare la perdita di informazioni riservate. È consigliabile disabilitare l'esplorazione directory nell'ambiente di produzione. Controllare attentamente quali sono le directory abilitate tramite UseStaticFiles o UseDirectoryBrowser. L'intera directory e le relative sottodirectory diventano pubblicamente accessibili. Archiviare i file adatti per la gestione al pubblico in una directory dedicata, ad esempio <content_root>/wwwroot. Separare questi file dalle visualizzazioni MVC, Razor dalle pagine, dai file di configurazione e così via.

  • Gli URL per il contenuto esposto con UseDirectoryBrowser e UseStaticFiles sono soggetti a distinzione tra maiuscole e minuscole e a limitazione di caratteri del file system sottostante. Ad esempio, Windows non fa distinzione tra maiuscole e minuscole, ma macOS e Linux non lo sono.

  • Le app ASP.NET Core ospitate in IIS usano il modulo ASP.NET Core per inoltrare tutte le richieste all'app, incluse le richieste di file statici. Il gestore di file statici IIS non viene usato e non ha la possibilità di gestire le richieste.

  • Completare la procedura seguente in Gestione IIS per rimuovere il gestore di file statici di IIS a livello di server o di sito Web:

    1. Passare alla funzionalità Moduli.
    2. Selezionare StaticFileModule nell'elenco.
    3. Fare clic su Rimuovi nell'intestazione laterale Azioni.

Warning

Se il gestore di file statici di IIS è abilitato e il modulo ASP.NET Core non è configurato correttamente, vengono usati i file statici. Ciò si verifica, ad esempio, se il web.config file non viene distribuito.

  • Inserire i file di codice, inclusi .cs e .cshtml, all'esterno della radice Web del progetto dell'app. Si crea quindi un separazione logica tra il contenuto sul lato client dell'app e il codice basato su server. In questo modo si impedisce la perdita del codice sul lato server.

Proprietà di MSBuild

Le tabelle seguenti illustrano le proprietà e le descrizioni dei metadati di MSBuild per i file statici.

Proprietà Description
EnableDefaultCompressedItems Abilita i modelli di inclusione/esclusione predefiniti per la compressione.
CompressionIncludePatterns Elenco delimitato da punto e virgola di modelli di file da includere per la compressione.
CompressionExcludePatterns Elenco delimitato da punto e virgola di modelli di file da escludere dalla compressione.
EnableDefaultCompressionFormats Abilita i formati di compressione predefiniti (Gzip e Brotli).
BuildCompressionFormats Formati di compressione da usare durante la compilazione.
PublishCompressionFormats Formati di compressione da usare durante la pubblicazione.
DisableBuildCompression Disabilita la compressione durante la compilazione.
CompressDiscoveredAssetsDuringBuild Comprime gli asset individuati durante la compilazione.
BrotliCompressionLevel Livello di compressione per l'algoritmo Brotli.
StaticWebAssetBuildCompressAllAssets Comprime tutti gli asset durante la compilazione, non solo gli asset individuati o calcolati durante una compilazione.
StaticWebAssetPublishCompressAllAssets Comprime tutti gli asset durante la pubblicazione, non solo gli asset individuati o calcolati durante una compilazione.
Proprietà Description
StaticWebAssetBasePath Percorso URL di base per tutti gli asset in una libreria.
StaticWebAssetsFingerprintContent Abilita l'impronta digitale del contenuto per il busting della cache.
StaticWebAssetFingerprintingEnabled Abilita la funzionalità di impronta digitale per gli asset Web statici.
StaticWebAssetsCacheDefineStaticWebAssetsEnabled Abilita la memorizzazione nella cache per le definizioni di asset Web statici.
StaticWebAssetEndpointExclusionPattern Modello per escludere gli endpoint.
Gruppo di articoli Description Metadati
StaticWebAssetContentTypeMapping Associa i modelli di file ai tipi di contenuto e alle intestazioni della cache per gli endpoint. Pattern, Cache
StaticWebAssetFingerprintPattern Definisce i modelli per l'applicazione di impronte digitali agli asset Web statici per il busting della cache. Pattern, Expression

Descrizioni dei metadati:

  • Pattern: modello GLOB usato per trovare le corrispondenze con i file. Per StaticWebAssetContentTypeMapping, corrisponde ai file per determinare il tipo di contenuto, ad esempio *.js per i file JavaScript. Per StaticWebAssetFingerprintPattern, identifica i file con più estensioni che richiedono un trattamento speciale per l'impronta digitale (ad esempio, *.lib.module.js).

  • Cache: specifica il valore dell'intestazione Cache-Control per il tipo di contenuto corrispondente. Questo controlla il comportamento di memorizzazione nella cache del browser , max-age=3600, must-revalidate ad esempio per i file multimediali.

  • Expression: definisce la modalità di inserimento dell'impronta digitale nel nome file. Il valore predefinito è #[.{FINGERPRINT}], che inserisce l'impronta digitale ({FINGERPRINT} segnaposto) prima dell'estensione.

L'esempio seguente esegue la mappatura del modello di file bitmap (.bmp) al image/bmp tipo di contenuto con il {CACHE HEADER} segnaposto che rappresenta l'intestazione Cache-Control da usare per endpoint senza impronta digitale:

<ItemGroup>
  <StaticWebAssetContentTypeMapping Include="image/bmp" Cache="{CACHE HEADER}" Pattern="*.bmp" />
</ItemGroup>

Opzioni di configurazione del runtime

Nella tabella seguente vengono descritte le opzioni di configurazione del runtime.

Chiave di configurazione Description
ReloadStaticAssetsAtRuntime Abilita il ricaricamento rapido in fase di sviluppo per gli asset statici: serve i file modificati della radice web (wwwroot), ricomputa ETag e ricomprime se necessario, anziché le versioni del manifesto della fase di build. L'impostazione predefinita è abilitata solo quando si gestisce un manifesto di compilazione a meno che non sia impostato in modo esplicito.
DisableStaticAssetNotFoundRuntimeFallback Quando true, elimina l'endpoint di fallback che gestisce i file appena aggiunti non presenti nel manifesto di compilazione. Quando false è assente, viene registrato un avviso con un fallback verificato per l'esistenza del file {**path} (GET/HEAD) e il file viene gestito con un oggetto calcolato ETag.
EnableStaticAssetsDevelopmentCaching Quando true, mantiene le intestazioni originali Cache-Control nei descrittori degli asset. Quando false è presente o assente, riscrive le intestazioni Cache-Control in no-cache per evitare un caching client aggressivo durante lo sviluppo.
EnableStaticAssetsDevelopmentIntegrity Quando true, mantiene le proprietà di integrità nei descrittori degli asset. Quando false è presente o assente, rimuove qualsiasi proprietà di integrità per evitare discrepanze quando i file cambiano durante lo sviluppo.

Risorse aggiuntive