File statici in ASP.NET Core
Nota
Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 8 di questo articolo.
Avviso
Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere Criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 8 di questo articolo.
Importante
Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Per la versione corrente, vedere la versione .NET 8 di questo articolo.
I file statici, ad esempio HTML, CSS, immagini e JavaScript, sono asset di un'app ASP.NET Core serve direttamente ai client per impostazione predefinita.
Per Blazor indicazioni sui file statici, che aggiunge o sostituisce le linee guida in questo articolo, vedere ASP.NET File statici coreBlazor.
Usare i file statici
I file statici vengono archiviati all'interno della directory radice Web del progetto. La directory predefinita è {content root}/wwwroot
, ma può essere modificata con il UseWebRoot metodo . Per altre informazioni, vedere Radice del contenuto e Radice Web.
Il metodo CreateBuilder imposta la radice del contenuto nella directory corrente:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.MapStaticAssets();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
I file statici sono accessibili tramite un percorso relativo alla radice Web. Ad esempio, i modelli di progetto applicazione Web contengono diverse cartelle all'interno della wwwroot
cartella :
wwwroot
css
js
lib
Prendere in considerazione un'app con il wwwroot/images/MyImage.jpg
file . Il formato URI per accedere a un file nella images
cartella è https://<hostname>/images/<image_file_name>
. Ad esempio, https://localhost:5001/images/MyImage.jpg
MapStaticAssets
La creazione di app Web con prestazioni elevate richiede l'ottimizzazione della distribuzione degli asset nel browser. Le possibili ottimizzazioni includono:
- Servire un determinato asset una volta fino a quando il file non cambia o il browser cancella la cache. Impostare l'intestazione ETag .
- Impedire al browser di usare asset obsoleti o non aggiornati dopo l'aggiornamento di un'app. Impostare l'intestazione Ultima modifica .
- Configurare le intestazioni di memorizzazione nella cache appropriate.
- Usare il middleware di memorizzazione nella cache.
- Gestire le versioni compresse degli asset, quando possibile.
- Usare una rete CDN per gestire gli asset più vicini all'utente.
- Ridurre al minimo le dimensioni degli asset serviti al browser. Questa ottimizzazione non include la minificazione.
MapStaticAssets sono convenzioni degli endpoint di routing che ottimizzano la distribuzione di asset statici in un'app. È progettato per funzionare con tutti i framework dell'interfaccia utente, tra cui Blazor, Razor Pages e MVC.
UseStaticFiles
gestisce anche i file statici, ma non fornisce lo stesso livello di ottimizzazione di MapStaticAssets
. Per un confronto tra UseStaticFiles
e , vedere Ottimizzazione della distribuzione di asset MapStaticAssets
Web statici.
Gestire i file nella radice Web
I modelli di app Web predefiniti chiamano il MapStaticAssets metodo in Program.cs
, che consente di gestire i file statici:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.MapStaticAssets();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
L'overload del metodo senza UseStaticFiles
parametri contrassegna i file nella radice Web come serveble. I riferimenti di wwwroot/images/MyImage.jpg
markup seguenti:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Nel markup precedente il carattere ~
tilde punta alla radice Web.
Usare i file all'esterno della radice Web
Si consideri una gerarchia di directory in cui i file statici da gestire si trovano all'esterno della radice Web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Una richiesta può accedere al red-rose.jpg
file configurando il middleware dei file statici come indicato di seguito:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(); //Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Nel codice precedente la gerarchia di directory MyStaticFiles viene esposta pubblicamente tramite il segmento dell'URI StaticFiles. Richiesta di gestione https://<hostname>/StaticFiles/images/red-rose.jpg
del red-rose.jpg
file.
I riferimenti di MyStaticFiles/images/red-rose.jpg
markup seguenti:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Per gestire i file da più posizioni, vedere Gestire i file da più posizioni.
Impostare le intestazioni della risposta HTTP
Un StaticFileOptions oggetto può essere usato per impostare le intestazioni di risposta HTTP. Oltre a configurare la gestione di file statici dalla radice Web, il codice seguente imposta l'intestazione Cache-Control :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
}
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Il codice precedente rende i file statici disponibili pubblicamente nella cache locale per una settimana.
Autorizzazione dei file statici
I modelli ASP.NET Core chiamano MapStaticAssets prima di chiamare 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
wwwroot
in , sono accessibili pubblicamente.
Per gestire i file statici in base all'autorizzazione:
- Archiviarli all'esterno di
wwwroot
. - Chiamare
UseStaticFiles
, specificando un percorso, dopo aver chiamatoUseAuthorization
. - Impostare i criteri di autorizzazione di fallback.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders;
using StaticFileAuth.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.AddRazorPages();
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
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.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.MapRazorPages();
app.Run();
Nel codice precedente, i criteri di autorizzazione di fallback richiedono l'autenticazione di tutti gli utenti. Gli endpoint, ad esempio controller, Razor pagine e così via, che specificano i propri requisiti di autorizzazione non usano i criteri di autorizzazione di fallback. Ad esempio, Razor Pages, controller o metodi di azione con [AllowAnonymous]
o [Authorize(PolicyName="MyPolicy")]
usano l'attributo di autorizzazione applicato anziché i criteri di autorizzazione di fallback.
RequireAuthenticatedUser aggiunge DenyAnonymousAuthorizationRequirement all'istanza corrente, che impone l'autenticazione dell'utente corrente.
Gli asset statici in wwwroot
sono accessibili pubblicamente perché il middleware dei file statici predefinito (app.UseStaticFiles();
) viene chiamato prima UseAuthentication
di . Gli asset statici nella cartella MyStaticFiles richiedono l'autenticazione. Il codice di esempio illustra questa operazione.
Un approccio alternativo per gestire i file in base all'autorizzazione consiste nel:
Archiviarli all'esterno di
wwwroot
e qualsiasi directory accessibile al middleware dei file statici.Gestirli tramite un metodo di azione a cui viene applicata l'autorizzazione e restituire un FileResult oggetto :
[Authorize] public class BannerImageModel : PageModel { private readonly IWebHostEnvironment _env; public BannerImageModel(IWebHostEnvironment env) => _env = env; public PhysicalFileResult OnGet() { var filePath = Path.Combine( _env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg"); return PhysicalFile(filePath, "image/jpeg"); } }
L'approccio precedente richiede una pagina o un endpoint per ogni file. Il codice seguente restituisce i file o carica i file per gli utenti autenticati:
app.MapGet("/files/{fileName}", IResult (string fileName) =>
{
var filePath = GetOrCreateFilePath(fileName);
if (File.Exists(filePath))
{
return TypedResults.PhysicalFile(filePath, fileDownloadName: $"{fileName}");
}
return TypedResults.NotFound("No file found with the supplied file name");
})
.WithName("GetFileByName")
.RequireAuthorization("AuthenticatedUsers");
app.MapPost("/files",
async (IFormFile file, LinkGenerator linker, HttpContext context) =>
{
// Don't rely on the file.FileName as it is only metadata that can be
// manipulated by the end-user. See 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");
app.Run();
IFormFile nell'esempio precedente usa il buffer di memoria per il caricamento. Per la gestione dello streaming di file di grandi dimensioni. Vedere Caricare file di grandi dimensioni con lo streaming.
Per l'esempio completo, vedere la cartella GitHub StaticFileAuth .
Esplorazione directory
L'esplorazione della directory consente l'elenco di directory all'interno di directory 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 AddDirectoryBrowser e UseDirectoryBrowser:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.MapStaticAssets();
var fileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.WebRootPath, "images"));
var requestPath = "/MyImages";
// Enable displaying browser links.
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Il codice precedente consente l'esplorazione della directory della cartella wwwroot/images usando l'URL https://<hostname>/MyImages
, con collegamenti a ogni file e cartella:
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 in tutte le app.
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 :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
UseDefaultFiles
deve essere chiamato prima di UseStaticFiles
per usare il file predefinito. UseDefaultFiles
è un rewriter URL che non serve il file.
Con UseDefaultFiles
, richiede a una cartella nella wwwroot
ricerca:
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. Nell'app di esempio, ad esempio, una richiesta da eseguire https://localhost:<port>/def/
default.html
da wwwroot/def
.
Il codice seguente modifica il nome file predefinito in mydefault.html
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
UseFileServer per i documenti predefiniti
UseFileServer combina le funzionalità di UseStaticFiles
, UseDefaultFiles
e facoltativamente UseDirectoryBrowser
.
Chiamare app.UseFileServer
per abilitare la gestione di file statici e il file predefinito. L'esplorazione della directory non è abilitata:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Il codice seguente abilita la gestione di file statici, il file predefinito e l'esplorazione della directory:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer(enableDirectoryBrowsing: true);
app.UseRouting();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Considerare la gerarchia di directory seguente:
wwwroot
css
images
js
MyStaticFiles
defaultFiles
default.html
image3.png
images
MyImage.jpg
Il codice seguente abilita la gestione di file statici, il file predefinito e l'esplorazione della directory di MyStaticFiles
:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
AddDirectoryBrowser deve essere chiamato quando il valore della EnableDirectoryBrowsing
proprietà è true
.
Usando la gerarchia di file e il codice precedenti, gli URL vengono risolti nel modo seguente:
URI | Response |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
Directory |
https://<hostname>/StaticFiles/defaultFiles |
MyStaticFiles/defaultFiles/default.html |
https://<hostname>/StaticFiles/defaultFiles/image3.png |
MyStaticFiles/defaultFiles//image3.png |
Se nella directory MyStaticFiles non esiste alcun file denominato predefinito, https://<hostname>/StaticFiles
restituisce l'elenco di directory con collegamenti selezionabili:
UseDefaultFiles ed UseDirectoryBrowser eseguire un reindirizzamento lato client dall'URI di destinazione senza un finale /
all'URI di destinazione con un oggetto finale /
. Ad esempio, da https://<hostname>/StaticFiles
a https://<hostname>/StaticFiles/
. Gli URL relativi all'interno della directory StaticFiles non sono validi senza una barra finale (/
) a meno che non venga usata l'opzione RedirectToAppendTrailingSlash di DefaultFilesOptions .
Classe FileExtensionContentTypeProvider
La FileExtensionContentTypeProvider classe contiene una proprietà Mappings che funge da mapping delle estensioni di file ai 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;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// 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
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
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 nella visualizzazione directory.
Il codice seguente consente di usare tipi sconosciuti ed esegue il rendering del file sconosciuto come immagine:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Con il codice precedente, una richiesta per un file con un tipo di contenuto sconosciuto viene restituita come immagine.
Avviso
L'abilitazione ServeUnknownFileTypes è un rischio per la sicurezza. È disabilitato per impostazione predefinita e ne è sconsigliato l'uso. La classe FileExtensionContentTypeProvider offre un'alternativa più sicura per usare i file con estensioni non standard.
Gestire i file da più posizioni
Si consideri la pagina seguente Razor che visualizza il /MyStaticFiles/image3.png
file:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
e UseFileServer
per impostazione predefinita il 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. L'esempio seguente chiama UseStaticFiles
due volte per gestire i file da e wwwroot
MyStaticFiles
:
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Uso del codice precedente:
- Viene visualizzato il
/MyStaticFiles/image3.png
file. - Gli helper AppendVersion tag immagine non vengono applicati perché gli helper tag dipendono da WebRootFileProvider.
WebRootFileProvider
non è stato aggiornato per includere laMyStaticFiles
cartella .
Il codice seguente aggiorna WebRootFileProvider
, che consente all'helper tag image di fornire una versione:
var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"));
var compositeProvider = new CompositeFileProvider(webRootProvider,
newPathProvider);
// Update the default provider.
app.Environment.WebRootFileProvider = compositeProvider;
app.MapStaticAssets();
Nota
L'approccio precedente si applica alle Razor app Pages e MVC. Per indicazioni applicabili a Blazor Web Apps, vedere ASP.NET File statici coreBlazor.
Considerazioni sulla sicurezza per i file statici
Avviso
UseDirectoryBrowser
e UseStaticFiles
possono perdere segreti. È 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
,UseStaticFiles
e sono soggetti alla distinzione tra maiuscole e minuscoleMapStaticAssets
e alle restrizioni dei 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:
- Passare alla funzionalità Moduli.
- Selezionare StaticFileModule nell'elenco.
- Fare clic su Rimuovi nell'intestazione laterale Azioni.
Avviso
Se il gestore di file statici di IIS è abilitato e il modulo ASP.NET Core non è configurato correttamente, vengono usati i file statici. Tale scenario si verifica ad esempio se il file web.config non è stato 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.
Gestire i file all'esterno di wwwroot aggiornando IWebHostEnvironment.WebRootPath
Quando IWebHostEnvironment.WebRootPath è impostato su una cartella diversa da wwwroot
:
- Nell'ambiente di sviluppo, gli asset statici presenti sia in
wwwroot
che nell'aggiornamentoIWebHostEnvironment.WebRootPath
vengono gestiti dawwwroot
. - In qualsiasi ambiente diverso dallo sviluppo, gli asset statici duplicati vengono serviti dalla cartella aggiornata
IWebHostEnvironment.WebRootPath
.
Si consideri un'app Web creata con il modello Web vuoto:
Contenente un
Index.html
file inwwwroot
ewwwroot-custom
.Con il file aggiornato
Program.cs
seguente che impostaWebRootPath = "wwwroot-custom"
:var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = args, // Look for static files in "wwwroot-custom" WebRootPath = "wwwroot-custom" }); var app = builder.Build(); app.UseDefaultFiles(); app.MapStaticAssets(); app.Run();
Nel codice precedente, richiede a /
:
- Nell'ambiente di sviluppo restituire
wwwroot/Index.html
- In qualsiasi ambiente diverso dalla restituzione dello sviluppo
wwwroot-custom/Index.html
Per assicurarsi che gli asset vengano wwwroot-custom
restituiti, usare uno degli approcci seguenti:
Eliminare asset denominati duplicati in
wwwroot
.Impostare
"ASPNETCORE_ENVIRONMENT"
in suProperties/launchSettings.json
qualsiasi valore diverso da"Development"
.Disabilitare completamente gli asset Web statici impostando
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
nel file di progetto. AVVISO, disabilitando gli asset Web statici, le Razor librerie di classi vengono disabilitate.Aggiungere il codice XML seguente al file di progetto:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
Il codice seguente viene aggiornato IWebHostEnvironment.WebRootPath
a un valore non di sviluppo, garantendo che venga restituito contenuto duplicato anziché wwwroot-custom
wwwroot
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Examine Hosting environment: logging value
EnvironmentName = Environments.Staging,
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
app.Environment.IsDevelopment().ToString());
app.UseDefaultFiles();
app.MapStaticAssets();
app.Run();
Risorse aggiuntive
I file statici, ad esempio HTML, CSS, immagini e JavaScript, sono asset di un'app ASP.NET Core serve direttamente ai client per impostazione predefinita.
Usare i file statici
I file statici vengono archiviati all'interno della directory radice Web del progetto. La directory predefinita è {content root}/wwwroot
, ma può essere modificata con il UseWebRoot metodo . Per altre informazioni, vedere Radice del contenuto e Radice Web.
Il metodo CreateBuilder imposta la radice del contenuto nella directory corrente:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
I file statici sono accessibili tramite un percorso relativo alla radice Web. Ad esempio, i modelli di progetto applicazione Web contengono diverse cartelle all'interno della wwwroot
cartella :
wwwroot
css
js
lib
È consigliabile creare la cartella wwwroot/images e aggiungere il wwwroot/images/MyImage.jpg
file. Il formato URI per accedere a un file nella images
cartella è https://<hostname>/images/<image_file_name>
. Ad esempio, https://localhost:5001/images/MyImage.jpg
Gestire i file nella radice Web
I modelli di app Web predefiniti chiamano il UseStaticFiles metodo in Program.cs
, che consente di gestire i file statici:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
L'overload del metodo senza UseStaticFiles
parametri contrassegna i file nella radice Web come serveble. I riferimenti di wwwroot/images/MyImage.jpg
markup seguenti:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Nel markup precedente il carattere ~
tilde punta alla radice Web.
Usare i file all'esterno della radice Web
Si consideri una gerarchia di directory in cui i file statici da gestire si trovano all'esterno della radice Web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Una richiesta può accedere al red-rose.jpg
file configurando il middleware dei file statici come indicato di seguito:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Nel codice precedente la gerarchia di directory MyStaticFiles viene esposta pubblicamente tramite il segmento dell'URI StaticFiles. Richiesta di gestione https://<hostname>/StaticFiles/images/red-rose.jpg
del red-rose.jpg
file.
I riferimenti di MyStaticFiles/images/red-rose.jpg
markup seguenti:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Per gestire i file da più posizioni, vedere Gestire i file da più posizioni.
Impostare le intestazioni della risposta HTTP
Un StaticFileOptions oggetto può essere usato per impostare le intestazioni di risposta HTTP. Oltre a configurare la gestione di file statici dalla radice Web, il codice seguente imposta l'intestazione Cache-Control :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
}
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Il codice precedente rende i file statici disponibili pubblicamente nella cache locale per una settimana (604800 secondi).
Autorizzazione dei file statici
I modelli ASP.NET Core chiamano UseStaticFiles prima di chiamare 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
wwwroot
in , sono accessibili pubblicamente.
Per gestire i file statici in base all'autorizzazione:
- Archiviarli all'esterno di
wwwroot
. - Chiamare
UseStaticFiles
, specificando un percorso, dopo aver chiamatoUseAuthorization
. - Impostare i criteri di autorizzazione di fallback.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders;
using StaticFileAuth.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.AddRazorPages();
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
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.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.MapRazorPages();
app.Run();
Nel codice precedente, i criteri di autorizzazione di fallback richiedono l'autenticazione di tutti gli utenti. Gli endpoint, ad esempio controller, Razor pagine e così via, che specificano i propri requisiti di autorizzazione non usano i criteri di autorizzazione di fallback. Ad esempio, Razor Pages, controller o metodi di azione con [AllowAnonymous]
o [Authorize(PolicyName="MyPolicy")]
usano l'attributo di autorizzazione applicato anziché i criteri di autorizzazione di fallback.
RequireAuthenticatedUser aggiunge DenyAnonymousAuthorizationRequirement all'istanza corrente, che impone l'autenticazione dell'utente corrente.
Gli asset statici in wwwroot
sono accessibili pubblicamente perché il middleware dei file statici predefinito (app.UseStaticFiles();
) viene chiamato prima UseAuthentication
di . Gli asset statici nella cartella MyStaticFiles richiedono l'autenticazione. Il codice di esempio illustra questa operazione.
Un approccio alternativo per gestire i file in base all'autorizzazione consiste nel:
Archiviarli all'esterno di
wwwroot
e qualsiasi directory accessibile al middleware dei file statici.Gestirli tramite un metodo di azione a cui viene applicata l'autorizzazione e restituire un FileResult oggetto :
[Authorize] public class BannerImageModel : PageModel { private readonly IWebHostEnvironment _env; public BannerImageModel(IWebHostEnvironment env) => _env = env; public PhysicalFileResult OnGet() { var filePath = Path.Combine( _env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg"); return PhysicalFile(filePath, "image/jpeg"); } }
L'approccio precedente richiede una pagina o un endpoint per ogni file. Il codice seguente restituisce i file o carica i file per gli utenti autenticati:
app.MapGet("/files/{fileName}", IResult (string fileName) =>
{
var filePath = GetOrCreateFilePath(fileName);
if (File.Exists(filePath))
{
return TypedResults.PhysicalFile(filePath, fileDownloadName: $"{fileName}");
}
return TypedResults.NotFound("No file found with the supplied file name");
})
.WithName("GetFileByName")
.RequireAuthorization("AuthenticatedUsers");
// IFormFile uses memory buffer for uploading. For handling large file use streaming instead.
// https://video2.skills-academy.com/aspnet/core/mvc/models/file-uploads#upload-large-files-with-streaming
app.MapPost("/files", async (IFormFile file, LinkGenerator linker, HttpContext context) =>
{
// Don't rely on the file.FileName as it is only metadata that can be manipulated by the end-user
// Take a look at 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");
app.Run();
Per l'esempio completo, vedere la cartella GitHub StaticFileAuth .
Esplorazione directory
L'esplorazione della directory consente l'elenco di directory all'interno di directory 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 AddDirectoryBrowser e UseDirectoryBrowser:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
var fileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.WebRootPath, "images"));
var requestPath = "/MyImages";
// Enable displaying browser links.
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Il codice precedente consente l'esplorazione della directory della cartella wwwroot/images usando l'URL https://<hostname>/MyImages
, con collegamenti a ogni file e cartella:
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 in tutte le app.
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 :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
UseDefaultFiles
deve essere chiamato prima di UseStaticFiles
per usare il file predefinito. UseDefaultFiles
è un rewriter URL che non serve il file.
Con UseDefaultFiles
, richiede a una cartella nella wwwroot
ricerca:
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 mydefault.html
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
UseFileServer per i documenti predefiniti
UseFileServer combina le funzionalità di UseStaticFiles
, UseDefaultFiles
e facoltativamente UseDirectoryBrowser
.
Chiamare app.UseFileServer
per abilitare la gestione di file statici e il file predefinito. L'esplorazione della directory non è abilitata:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Il codice seguente abilita la gestione di file statici, il file predefinito e l'esplorazione della directory:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer(enableDirectoryBrowsing: true);
app.UseRouting();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Considerare la gerarchia di directory seguente:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
Il codice seguente abilita la gestione di file statici, il file predefinito e l'esplorazione della directory di MyStaticFiles
:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
AddDirectoryBrowser deve essere chiamato quando il valore della EnableDirectoryBrowsing
proprietà è true
.
Usando la gerarchia di file e il codice precedenti, gli URL vengono risolti nel modo seguente:
URI | Response |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Se nella directory MyStaticFiles non esiste alcun file denominato predefinito, https://<hostname>/StaticFiles
restituisce l'elenco di directory con collegamenti selezionabili:
UseDefaultFiles ed UseDirectoryBrowser eseguire un reindirizzamento lato client dall'URI di destinazione senza un finale /
all'URI di destinazione con un oggetto finale /
. Ad esempio, da https://<hostname>/StaticFiles
a https://<hostname>/StaticFiles/
. Gli URL relativi all'interno della directory StaticFiles non sono validi senza una barra finale (/
) a meno che non venga usata l'opzione RedirectToAppendTrailingSlash di DefaultFilesOptions .
Classe FileExtensionContentTypeProvider
La FileExtensionContentTypeProvider classe contiene una Mappings
proprietà che funge da mapping delle estensioni di file ai 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;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// 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
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
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 nella visualizzazione directory.
Il codice seguente consente di usare tipi sconosciuti ed esegue il rendering del file sconosciuto come immagine:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Con il codice precedente, una richiesta per un file con un tipo di contenuto sconosciuto viene restituita come immagine.
Avviso
L'abilitazione ServeUnknownFileTypes è un rischio per la sicurezza. È disabilitato per impostazione predefinita e ne è sconsigliato l'uso. La classe FileExtensionContentTypeProvider offre un'alternativa più sicura per usare i file con estensioni non standard.
Gestire i file da più posizioni
Si consideri la pagina seguente Razor che visualizza il /MyStaticFiles/image3.png
file:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
e UseFileServer
per impostazione predefinita il 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. L'esempio seguente chiama UseStaticFiles
due volte per gestire i file da e wwwroot
MyStaticFiles
:
app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Uso del codice precedente:
- Viene visualizzato il
/MyStaticFiles/image3.png
file. - Gli helper AppendVersion tag immagine non vengono applicati perché gli helper tag dipendono da WebRootFileProvider.
WebRootFileProvider
non è stato aggiornato per includere laMyStaticFiles
cartella .
Il codice seguente aggiorna WebRootFileProvider
, che consente all'helper tag image di fornire una versione:
var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"));
var compositeProvider = new CompositeFileProvider(webRootProvider,
newPathProvider);
// Update the default provider.
app.Environment.WebRootFileProvider = compositeProvider;
app.UseStaticFiles();
Nota
L'approccio precedente si applica alle Razor app Pages e MVC. Per indicazioni applicabili a Blazor Web Apps, vedere ASP.NET File statici coreBlazor.
Considerazioni sulla sicurezza per i file statici
Avviso
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
eUseStaticFiles
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:
- Passare alla funzionalità Moduli.
- Selezionare StaticFileModule nell'elenco.
- Fare clic su Rimuovi nell'intestazione laterale Azioni.
Avviso
Se il gestore di file statici di IIS è abilitato e il modulo ASP.NET Core non è configurato correttamente, vengono usati i file statici. Tale scenario si verifica ad esempio se il file web.config non è stato 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.
Gestire i file all'esterno di wwwroot aggiornando IWebHostEnvironment.WebRootPath
Quando IWebHostEnvironment.WebRootPath è impostato su una cartella diversa da wwwroot
:
- Nell'ambiente di sviluppo, gli asset statici presenti sia in
wwwroot
che nell'aggiornamentoIWebHostEnvironment.WebRootPath
vengono gestiti dawwwroot
. - In qualsiasi ambiente diverso dallo sviluppo, gli asset statici duplicati vengono serviti dalla cartella aggiornata
IWebHostEnvironment.WebRootPath
.
Si consideri un'app Web creata con il modello Web vuoto:
Contenente un
Index.html
file inwwwroot
ewwwroot-custom
.Con il file aggiornato
Program.cs
seguente che impostaWebRootPath = "wwwroot-custom"
:var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = args, // Look for static files in "wwwroot-custom" WebRootPath = "wwwroot-custom" }); var app = builder.Build(); app.UseDefaultFiles(); app.UseStaticFiles(); app.Run();
Nel codice precedente, richiede a /
:
- Nell'ambiente di sviluppo restituire
wwwroot/Index.html
- In qualsiasi ambiente diverso dalla restituzione dello sviluppo
wwwroot-custom/Index.html
Per assicurarsi che gli asset vengano wwwroot-custom
restituiti, usare uno degli approcci seguenti:
Eliminare asset denominati duplicati in
wwwroot
.Impostare
"ASPNETCORE_ENVIRONMENT"
in suProperties/launchSettings.json
qualsiasi valore diverso da"Development"
.Disabilitare completamente gli asset Web statici impostando
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
nel file di progetto. AVVISO, disabilitando gli asset Web statici, le Razor librerie di classi vengono disabilitate.Aggiungere il codice JSON seguente al file di progetto:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
Il codice seguente viene aggiornato IWebHostEnvironment.WebRootPath
a un valore non di sviluppo, garantendo che venga restituito contenuto duplicato anziché wwwroot-custom
wwwroot
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Examine Hosting environment: logging value
EnvironmentName = Environments.Staging,
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
app.Environment.IsDevelopment().ToString());
app.UseDefaultFiles();
app.UseStaticFiles();
app.Run();
Risorse aggiuntive
Di Rick Anderson e Kirk Larkin
I file statici, ad esempio HTML, CSS, immagini e JavaScript, sono asset di un'app ASP.NET Core serve direttamente ai client per impostazione predefinita.
Usare i file statici
I file statici vengono archiviati all'interno della directory radice Web del progetto. La directory predefinita è {content root}/wwwroot
, ma può essere modificata con il UseWebRoot metodo . Per altre informazioni, vedere Radice del contenuto e Radice Web.
Il metodo CreateBuilder imposta la radice del contenuto nella directory corrente:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
I file statici sono accessibili tramite un percorso relativo alla radice Web. Ad esempio, i modelli di progetto applicazione Web contengono diverse cartelle all'interno della wwwroot
cartella :
wwwroot
css
js
lib
È consigliabile creare la cartella wwwroot/images e aggiungere il wwwroot/images/MyImage.jpg
file. Il formato URI per accedere a un file nella images
cartella è https://<hostname>/images/<image_file_name>
. Ad esempio, https://localhost:5001/images/MyImage.jpg
Gestire i file nella radice Web
I modelli di app Web predefiniti chiamano il UseStaticFiles metodo in Program.cs
, che consente di gestire i file statici:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
L'overload del metodo senza UseStaticFiles
parametri contrassegna i file nella radice Web come serveble. I riferimenti di wwwroot/images/MyImage.jpg
markup seguenti:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Nel markup precedente il carattere ~
tilde punta alla radice Web.
Usare i file all'esterno della radice Web
Si consideri una gerarchia di directory in cui i file statici da gestire si trovano all'esterno della radice Web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Una richiesta può accedere al red-rose.jpg
file configurando il middleware dei file statici come indicato di seguito:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Nel codice precedente la gerarchia di directory MyStaticFiles viene esposta pubblicamente tramite il segmento dell'URI StaticFiles. Richiesta di gestione https://<hostname>/StaticFiles/images/red-rose.jpg
del red-rose.jpg
file.
I riferimenti di MyStaticFiles/images/red-rose.jpg
markup seguenti:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Per gestire i file da più posizioni, vedere Gestire i file da più posizioni.
Impostare le intestazioni della risposta HTTP
Un StaticFileOptions oggetto può essere usato per impostare le intestazioni di risposta HTTP. Oltre a configurare la gestione di file statici dalla radice Web, il codice seguente imposta l'intestazione Cache-Control :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
}
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Il codice precedente rende i file statici disponibili pubblicamente nella cache locale per una settimana (604800 secondi).
Autorizzazione dei file statici
I modelli ASP.NET Core chiamano UseStaticFiles prima di chiamare 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
wwwroot
in , sono accessibili pubblicamente.
Per gestire i file statici in base all'autorizzazione:
- Archiviarli all'esterno di
wwwroot
. - Chiamare
UseStaticFiles
, specificando un percorso, dopo aver chiamatoUseAuthorization
. - Impostare i criteri di autorizzazione di fallback.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders;
using StaticFileAuth.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.AddRazorPages();
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
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.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.MapRazorPages();
app.Run();
Nel codice precedente, i criteri di autorizzazione di fallback richiedono l'autenticazione di tutti gli utenti. Gli endpoint, ad esempio controller, Razor pagine e così via, che specificano i propri requisiti di autorizzazione non usano i criteri di autorizzazione di fallback. Ad esempio, Razor Pages, controller o metodi di azione con [AllowAnonymous]
o [Authorize(PolicyName="MyPolicy")]
usano l'attributo di autorizzazione applicato anziché i criteri di autorizzazione di fallback.
RequireAuthenticatedUser aggiunge DenyAnonymousAuthorizationRequirement all'istanza corrente, che impone l'autenticazione dell'utente corrente.
Gli asset statici in wwwroot
sono accessibili pubblicamente perché il middleware dei file statici predefinito (app.UseStaticFiles();
) viene chiamato prima UseAuthentication
di . Gli asset statici nella cartella MyStaticFiles richiedono l'autenticazione. Il codice di esempio illustra questa operazione.
Un approccio alternativo per gestire i file in base all'autorizzazione consiste nel:
- Archiviarli all'esterno di
wwwroot
e qualsiasi directory accessibile al middleware dei file statici. - Gestirli tramite un metodo di azione a cui viene applicata l'autorizzazione e restituire un FileResult oggetto :
[Authorize]
public class BannerImageModel : PageModel
{
private readonly IWebHostEnvironment _env;
public BannerImageModel(IWebHostEnvironment env) =>
_env = env;
public PhysicalFileResult OnGet()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
}
Esplorazione directory
L'esplorazione della directory consente l'elenco di directory all'interno di directory 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 AddDirectoryBrowser e UseDirectoryBrowser:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
var fileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.WebRootPath, "images"));
var requestPath = "/MyImages";
// Enable displaying browser links.
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Il codice precedente consente l'esplorazione della directory della cartella wwwroot/images usando l'URL https://<hostname>/MyImages
, con collegamenti a ogni file e cartella:
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 in tutte le app.
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 :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
UseDefaultFiles
deve essere chiamato prima di UseStaticFiles
per usare il file predefinito. UseDefaultFiles
è un rewriter URL che non serve il file.
Con UseDefaultFiles
, richiede a una cartella nella wwwroot
ricerca:
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 mydefault.html
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
UseFileServer per i documenti predefiniti
UseFileServer combina le funzionalità di UseStaticFiles
, UseDefaultFiles
e facoltativamente UseDirectoryBrowser
.
Chiamare app.UseFileServer
per abilitare la gestione di file statici e il file predefinito. L'esplorazione della directory non è abilitata:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Il codice seguente abilita la gestione di file statici, il file predefinito e l'esplorazione della directory:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer(enableDirectoryBrowsing: true);
app.UseRouting();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Considerare la gerarchia di directory seguente:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
Il codice seguente abilita la gestione di file statici, il file predefinito e l'esplorazione della directory di MyStaticFiles
:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
AddDirectoryBrowser deve essere chiamato quando il valore della EnableDirectoryBrowsing
proprietà è true
.
Usando la gerarchia di file e il codice precedenti, gli URL vengono risolti nel modo seguente:
URI | Response |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Se nella directory MyStaticFiles non esiste alcun file denominato predefinito, https://<hostname>/StaticFiles
restituisce l'elenco di directory con collegamenti selezionabili:
UseDefaultFiles ed UseDirectoryBrowser eseguire un reindirizzamento lato client dall'URI di destinazione senza un finale /
all'URI di destinazione con un oggetto finale /
. Ad esempio, da https://<hostname>/StaticFiles
a https://<hostname>/StaticFiles/
. Gli URL relativi all'interno della directory StaticFiles non sono validi senza una barra finale (/
) a meno che non venga usata l'opzione RedirectToAppendTrailingSlash di DefaultFilesOptions .
Classe FileExtensionContentTypeProvider
La FileExtensionContentTypeProvider classe contiene una Mappings
proprietà che funge da mapping delle estensioni di file ai 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;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// 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
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
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 nella visualizzazione directory.
Il codice seguente consente di usare tipi sconosciuti ed esegue il rendering del file sconosciuto come immagine:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Con il codice precedente, una richiesta per un file con un tipo di contenuto sconosciuto viene restituita come immagine.
Avviso
L'abilitazione ServeUnknownFileTypes è un rischio per la sicurezza. È disabilitato per impostazione predefinita e ne è sconsigliato l'uso. La classe FileExtensionContentTypeProvider offre un'alternativa più sicura per usare i file con estensioni non standard.
Gestire i file da più posizioni
Si consideri la pagina seguente Razor che visualizza il /MyStaticFiles/image3.png
file:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
e UseFileServer
per impostazione predefinita il 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. L'esempio seguente chiama UseStaticFiles
due volte per gestire i file da e wwwroot
MyStaticFiles
:
app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Uso del codice precedente:
- Viene visualizzato il
/MyStaticFiles/image3.png
file. - Gli helper AppendVersion tag immagine non vengono applicati perché gli helper tag dipendono da WebRootFileProvider.
WebRootFileProvider
non è stato aggiornato per includere laMyStaticFiles
cartella .
Il codice seguente aggiorna WebRootFileProvider
, che consente all'helper tag image di fornire una versione:
var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"));
var compositeProvider = new CompositeFileProvider(webRootProvider,
newPathProvider);
// Update the default provider.
app.Environment.WebRootFileProvider = compositeProvider;
app.UseStaticFiles();
Considerazioni sulla sicurezza per i file statici
Avviso
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
eUseStaticFiles
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:
- Passare alla funzionalità Moduli.
- Selezionare StaticFileModule nell'elenco.
- Fare clic su Rimuovi nell'intestazione laterale Azioni.
Avviso
Se il gestore di file statici di IIS è abilitato e il modulo ASP.NET Core non è configurato correttamente, vengono usati i file statici. Tale scenario si verifica ad esempio se il file web.config non è stato 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.
Gestire i file all'esterno di wwwroot aggiornando IWebHostEnvironment.WebRootPath
Quando IWebHostEnvironment.WebRootPath è impostato su una cartella diversa da wwwroot
:
- Nell'ambiente di sviluppo, gli asset statici presenti sia in
wwwroot
che nell'aggiornamentoIWebHostEnvironment.WebRootPath
vengono gestiti dawwwroot
. - In qualsiasi ambiente diverso dallo sviluppo, gli asset statici duplicati vengono serviti dalla cartella aggiornata
IWebHostEnvironment.WebRootPath
.
Si consideri un'app Web creata con il modello Web vuoto:
Contenente un
Index.html
file inwwwroot
ewwwroot-custom
.Con il file aggiornato
Program.cs
seguente che impostaWebRootPath = "wwwroot-custom"
:var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = args, // Look for static files in "wwwroot-custom" WebRootPath = "wwwroot-custom" }); var app = builder.Build(); app.UseDefaultFiles(); app.UseStaticFiles(); app.Run();
Nel codice precedente, richiede a /
:
- Nell'ambiente di sviluppo restituire
wwwroot/Index.html
- In qualsiasi ambiente diverso dalla restituzione dello sviluppo
wwwroot-custom/Index.html
Per assicurarsi che gli asset vengano wwwroot-custom
restituiti, usare uno degli approcci seguenti:
Eliminare asset denominati duplicati in
wwwroot
.Impostare
"ASPNETCORE_ENVIRONMENT"
in suProperties/launchSettings.json
qualsiasi valore diverso da"Development"
.Disabilitare completamente gli asset Web statici impostando
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
nel file di progetto. AVVISO, disabilitando gli asset Web statici, le Razor librerie di classi vengono disabilitate.Aggiungere il codice JSON seguente al file di progetto:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
Il codice seguente viene aggiornato IWebHostEnvironment.WebRootPath
a un valore non di sviluppo, garantendo che venga restituito contenuto duplicato anziché wwwroot-custom
wwwroot
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Examine Hosting environment: logging value
EnvironmentName = Environments.Staging,
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
app.Environment.IsDevelopment().ToString());
app.UseDefaultFiles();
app.UseStaticFiles();
app.Run();
Risorse aggiuntive
Di Rick Anderson e Kirk Larkin
I file statici, ad esempio HTML, CSS, immagini e JavaScript, sono asset di un'app ASP.NET Core serve direttamente ai client per impostazione predefinita.
Visualizzare o scaricare il codice di esempio (procedura per il download)
Usare i file statici
I file statici vengono archiviati all'interno della directory radice Web del progetto. La directory predefinita è {content root}/wwwroot
, ma può essere modificata con il UseWebRoot metodo . Per altre informazioni, vedere Radice del contenuto e Radice Web.
Il metodo CreateDefaultBuilder imposta la radice del contenuto nella directory corrente:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
Il codice precedente è stato creato con il modello di app Web.
I file statici sono accessibili tramite un percorso relativo alla radice Web. Ad esempio, i modelli di progetto applicazione Web contengono diverse cartelle all'interno della wwwroot
cartella :
wwwroot
css
js
lib
È consigliabile creare la cartella wwwroot/images e aggiungere il wwwroot/images/MyImage.jpg
file. Il formato URI per accedere a un file nella images
cartella è https://<hostname>/images/<image_file_name>
. Ad esempio, https://localhost:5001/images/MyImage.jpg
Gestire i file nella radice Web
I modelli di app Web predefiniti chiamano il UseStaticFiles metodo in Startup.Configure
, che consente di gestire i file statici:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
L'overload del metodo senza UseStaticFiles
parametri contrassegna i file nella radice Web come serveble. I riferimenti di wwwroot/images/MyImage.jpg
markup seguenti:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Nel codice precedente il carattere ~/
tilde punta alla radice Web.
Usare i file all'esterno della radice Web
Si consideri una gerarchia di directory in cui i file statici da gestire si trovano all'esterno della radice Web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Una richiesta può accedere al red-rose.jpg
file configurando il middleware dei file statici come indicato di seguito:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// using Microsoft.Extensions.FileProviders;
// using System.IO;
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Nel codice precedente la gerarchia di directory MyStaticFiles viene esposta pubblicamente tramite il segmento dell'URI StaticFiles. Richiesta di gestione https://<hostname>/StaticFiles/images/red-rose.jpg
del red-rose.jpg
file.
I riferimenti di MyStaticFiles/images/red-rose.jpg
markup seguenti:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Impostare le intestazioni della risposta HTTP
Un StaticFileOptions oggetto può essere usato per impostare le intestazioni di risposta HTTP. Oltre a configurare la gestione di file statici dalla radice Web, il codice seguente imposta l'intestazione Cache-Control
:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
const string cacheMaxAge = "604800";
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
// using Microsoft.AspNetCore.Http;
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAge}");
}
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Il codice precedente imposta max-age su 604800 secondi (7 giorni).
Autorizzazione dei file statici
I modelli ASP.NET Core chiamano UseStaticFiles prima di chiamare 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
wwwroot
in , sono accessibili pubblicamente.
Per gestire i file statici in base all'autorizzazione:
- Archiviarli all'esterno di
wwwroot
. - Chiamare
UseStaticFiles
, specificando un percorso, dopo aver chiamatoUseAuthorization
. - Impostare i criteri di autorizzazione di fallback.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// wwwroot css, JavaScript, and images don't require authentication.
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddRazorPages();
services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
}
// Remaining code ommitted for brevity.
Nel codice precedente, i criteri di autorizzazione di fallback richiedono l'autenticazione di tutti gli utenti. Gli endpoint, ad esempio controller, Razor pagine e così via, che specificano i propri requisiti di autorizzazione non usano i criteri di autorizzazione di fallback. Ad esempio, Razor Pages, controller o metodi di azione con [AllowAnonymous]
o [Authorize(PolicyName="MyPolicy")]
usano l'attributo di autorizzazione applicato anziché i criteri di autorizzazione di fallback.
RequireAuthenticatedUser aggiunge DenyAnonymousAuthorizationRequirement all'istanza corrente, che impone l'autenticazione dell'utente corrente.
Gli asset statici in wwwroot
sono accessibili pubblicamente perché il middleware dei file statici predefinito (app.UseStaticFiles();
) viene chiamato prima UseAuthentication
di . Gli asset statici nella cartella MyStaticFiles richiedono l'autenticazione. Il codice di esempio illustra questa operazione.
Un approccio alternativo per gestire i file in base all'autorizzazione consiste nel:
- Archiviarli all'esterno di
wwwroot
e qualsiasi directory accessibile al middleware dei file statici. - Gestirli tramite un metodo di azione a cui viene applicata l'autorizzazione e restituire un FileResult oggetto :
[Authorize]
public IActionResult BannerImage()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
Esplorazione directory
L'esplorazione della directory consente l'elenco di directory all'interno di directory 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:
- AddDirectoryBrowser in
Startup.ConfigureServices
. - UseDirectoryBrowser in
Startup.Configure
.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDirectoryBrowser();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// using Microsoft.Extensions.FileProviders;
// using System.IO;
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Il codice precedente consente l'esplorazione della directory della cartella wwwroot/images usando l'URL https://<hostname>/MyImages
, con collegamenti a ogni file e cartella:
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 :
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
UseDefaultFiles
deve essere chiamato prima di UseStaticFiles
per usare il file predefinito. UseDefaultFiles
è un rewriter URL che non serve il file.
Con UseDefaultFiles
, richiede a una cartella nella wwwroot
ricerca:
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 mydefault.html
:
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
Il codice seguente mostra Startup.Configure
con il codice precedente:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
UseFileServer per i documenti predefiniti
UseFileServer combina le funzionalità di UseStaticFiles
, UseDefaultFiles
e facoltativamente UseDirectoryBrowser
.
Chiamare app.UseFileServer
per abilitare la gestione di file statici e il file predefinito. L'esplorazione directory non è abilitata. Il codice seguente mostra Startup.Configure
con UseFileServer
:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Il codice seguente abilita la gestione di file statici, il file predefinito e l'esplorazione della directory:
app.UseFileServer(enableDirectoryBrowsing: true);
Il codice seguente mostra Startup.Configure
con il codice precedente:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer(enableDirectoryBrowsing: true);
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Considerare la gerarchia di directory seguente:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
Il codice seguente abilita la gestione di file statici, il file predefinito e l'esplorazione della directory di MyStaticFiles
:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDirectoryBrowser();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(); // For the wwwroot folder.
// using Microsoft.Extensions.FileProviders;
// using System.IO;
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
AddDirectoryBrowser deve essere chiamato quando il valore della EnableDirectoryBrowsing
proprietà è true
.
Dall'uso della gerarchia di file e del codice precedente ne deriva quanto segue:
URI | Response |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Se nella directory MyStaticFiles non esiste alcun file denominato predefinito, https://<hostname>/StaticFiles
restituisce l'elenco di directory con collegamenti selezionabili:
UseDefaultFiles ed UseDirectoryBrowser eseguire un reindirizzamento lato client dall'URI di destinazione senza un finale /
all'URI di destinazione con un oggetto finale /
. Ad esempio, da https://<hostname>/StaticFiles
a https://<hostname>/StaticFiles/
. Gli URL relativi all'interno della directory StaticFiles non sono validi senza una barra finale (/
).
Classe FileExtensionContentTypeProvider
La FileExtensionContentTypeProvider classe contiene una Mappings
proprietà che funge da mapping delle estensioni di file ai 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;
// 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 = "/MyImages",
ContentTypeProvider = provider
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
Il codice seguente mostra Startup.Configure
con il codice precedente:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// 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 = "/MyImages",
ContentTypeProvider = provider
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
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 nella visualizzazione directory.
Il codice seguente consente di usare tipi sconosciuti ed esegue il rendering del file sconosciuto come immagine:
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
Il codice seguente mostra Startup.Configure
con il codice precedente:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Con il codice precedente, una richiesta per un file con un tipo di contenuto sconosciuto viene restituita come immagine.
Avviso
L'abilitazione ServeUnknownFileTypes è un rischio per la sicurezza. È disabilitato per impostazione predefinita e ne è sconsigliato l'uso. La classe FileExtensionContentTypeProvider offre un'alternativa più sicura per usare i file con estensioni non standard.
Gestire i file da più posizioni
UseStaticFiles
e UseFileServer
per impostazione predefinita il 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 altre informazioni, vedere questo problema in GitHub.
Considerazioni sulla sicurezza per i file statici
Avviso
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
eUseStaticFiles
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:
- Passare alla funzionalità Moduli.
- Selezionare StaticFileModule nell'elenco.
- Fare clic su Rimuovi nell'intestazione laterale Azioni.
Avviso
Se il gestore di file statici di IIS è abilitato e il modulo ASP.NET Core non è configurato correttamente, vengono usati i file statici. Tale scenario si verifica ad esempio se il file web.config non è stato 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.