File statici in ASP.NET Core
Nota
Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 9 di questo articolo.
Avviso
Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere i criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 9 di questo articolo.
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 9 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.
Servire file statici
I file statici vengono archiviati all'interno della web directory root del progetto. La directory predefinita è {content root}/wwwroot
, ma può essere modificata con il UseWebRoot metodo . Per ulteriori 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
Distribuire 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 UseStaticFiles
senza parametri contrassegna i file nella radice web come servibili. I seguenti riferimenti markup di wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Nel markup precedente, il carattere tilde ~
punta alla radice del web.
Distribuire file al di fuori della radice del documento 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. Una richiesta a https://<hostname>/StaticFiles/images/red-rose.jpg
serve il file red-rose.jpg
.
Il seguente markup fa riferimento a MyStaticFiles/images/red-rose.jpg
.
<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 il servizio 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 forniti dal middleware dei file statici, come quelli sotto
wwwroot
, 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 i controller, Razor le pagine e così via, che specificano i propri requisiti di autorizzazione non usano la policy di autorizzazione di fallback. Ad esempio, Razor Pagine, controller o metodi di azione con [AllowAnonymous]
o [Authorize(PolicyName="MyPolicy")]
usano l'attributo di autorizzazione applicato anziché la politica di autorizzazione di fallback.
RequireAuthenticatedUser aggiunge DenyAnonymousAuthorizationRequirement all'istanza corrente, che impone l'autenticazione dell'utente corrente.
Gli asset statici in wwwroot
sono accessibili pubblicamente perché il middleware per i file statici predefinito (app.UseStaticFiles();
) viene chiamato prima di UseAuthentication
. 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:
Conservarli all'esterno di
wwwroot
e di 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://learn.microsoft.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();
Vedere la cartella GitHub StaticFileAuth per l'esempio completo.
Esplorazione directory
La navigazione delle directory consente di elencare le directory all'interno di quelle specificate.
L'esplorazione della directory è disabilitata per impostazione predefinita per motivi di sicurezza. Per altre informazioni, vedere Considerazioni sulla sicurezza per i file statici.
Abilitare l'esplorazione della directory con 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
, le richieste a una cartella in wwwroot
vengono cercate:
default.htm
default.html
index.htm
index.html
Il primo file trovato dall'elenco viene fornito come se la richiesta includa il nome del file. L'URL del browser continua a riflettere l'URI richiesto.
Il codice seguente modifica il nome file predefinito in 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();
Considera la seguente gerarchia di directory:
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 | Risposta |
---|---|
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 eseguono un reindirizzamento lato client dall'URI di destinazione senza un finale /
all'URI di destinazione con un 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 .
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 nell'elenco 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">
Per impostazione predefinita, UseStaticFiles
e UseFileServer
sono impostati al provider di file che punta a wwwroot
. Altre istanze di UseStaticFiles
e UseFileServer
possono essere fornite con altri provider di file per gestire i file da altre posizioni. L'esempio seguente chiama UseStaticFiles
due volte per servire i file da entrambe wwwroot
e 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 Tag Helper per le immaginiAppendVersion non vengono applicati perché i Tag Helper dipendono da WebRootFileProvider.
WebRootFileProvider
non è stato aggiornato per includere laMyStaticFiles
cartella .
Il codice seguente aggiorna WebRootFileProvider
, che consente all'Image Tag Helper di generare 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 Core Blazor file statici.
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 da quello di 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 file
Index.html
inwwwroot
ewwwroot-custom
.Con il seguente file
Program.cs
aggiornato 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 dallo sviluppo, restituisce
wwwroot-custom/Index.html
Per assicurarsi che gli asset da wwwroot-custom
vengano restituiti, utilizzare uno degli approcci seguenti:
Eliminare asset denominati duplicati in
wwwroot
.Impostare
"ASPNETCORE_ENVIRONMENT"
inProperties/launchSettings.json
a 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.
Servire i file statici
I file statici vengono archiviati all'interno della directory web root del progetto. La directory predefinita è {content root}/wwwroot
, ma può essere modificata con il UseWebRoot metodo . Per ulteriori 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 parametri contrassegna i file nella directory principale del web come servibili. I seguenti riferimenti markup: wwwroot/images/MyImage.jpg
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Nel markup precedente, il carattere tilde ~
punta alla radice del web.
Fornire 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. Una richiesta a https://<hostname>/StaticFiles/images/red-rose.jpg
serve il file red-rose.jpg
.
I seguenti riferimenti markup MyStaticFiles/images/red-rose.jpg
:
<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 serviti dal middleware dei file statici, come quelli sotto
wwwroot
, 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, come i controller, le Razor Pagine, ecc., che specificano i propri requisiti di autorizzazione non usano la politica di autorizzazione fallback. Ad esempio, Razor pagine, controller, o metodi di azione con [AllowAnonymous]
o [Authorize(PolicyName="MyPolicy")]
utilizzano l'attributo di autorizzazione applicato anziché la politica di autorizzazione di fallback.
RequireAuthenticatedUser aggiunge DenyAnonymousAuthorizationRequirement all'istanza corrente, che impone l'autenticazione dell'utente corrente.
Gli asset statici in wwwroot
sono accessibili pubblicamente perché il middleware dei file statici predefinito (app.UseStaticFiles();
) viene chiamato prima di UseAuthentication
. 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 di qualsiasi altra 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 cartella
La navigazione delle directory permette la visualizzazione dell'elenco delle 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();
Considera 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 | Risposta |
---|---|
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 e UseDirectoryBrowser eseguono un reindirizzamento lato client dall'URI di destinazione senza una barra finale /
all'URI di destinazione con una barra 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 la navigazione delle directory, viene visualizzato un collegamento al file nella visualizzazione della 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 puntano al provider di file che punta a wwwroot
. Altre istanze di UseStaticFiles
e UseFileServer
possono essere fornite con altri provider di file per gestire i file da altre posizioni. L'esempio seguente chiama UseStaticFiles
due volte per servire i file sia da wwwroot
che da 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 Tag Helper ImmagineAppendVersion non vengono applicati perché i Tag Helper 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 delle 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 da quello di sviluppo, le risorse statiche duplicate vengono servite 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 seguente file
Program.cs
aggiornato 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, le richieste a /
:
- Nell'ambiente di sviluppo restituire
wwwroot/Index.html
- In qualsiasi ambiente diverso dallo sviluppo, restituisci
wwwroot-custom/Index.html
Per garantire che gli asset di wwwroot-custom
vengano restituiti, utilizzare una delle seguenti opzioni:
Rimuovi gli asset con nomi duplicati in
wwwroot
.Impostare
"ASPNETCORE_ENVIRONMENT"
inProperties/launchSettings.json
su un 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 aggiorna IWebHostEnvironment.WebRootPath
a un valore non di sviluppo, garantendo che il contenuto duplicato venga restituito da wwwroot-custom
anziché da 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)
Fornire file statici
I file statici vengono archiviati all'interno della directory Web radice del progetto. La directory predefinita è {content root}/wwwroot
, ma può essere modificata con il UseWebRoot metodo . Per ulteriori 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
Servire 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 parametri contrassegna i file nella radice web come servibili. Il markup seguente fa riferimento a wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Nel codice precedente, il carattere tilde ~/
punta alla radice web.
Fornire file al di fuori della radice del sito
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. Una richiesta a https://<hostname>/StaticFiles/images/red-rose.jpg
serve il file red-rose.jpg
.
I seguenti riferimenti al markup MyStaticFiles/images/red-rose.jpg
:
<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 forniti dal middleware per file statici, come quelli sotto
wwwroot
, 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 sotto wwwroot
sono accessibili pubblicamente perché il middleware dei file statici predefinito (app.UseStaticFiles();
) viene chiamato prima di UseAuthentication
. 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 al di fuori di
wwwroot
e di qualsiasi directory accessibile al middleware per i file statici. - Servili tramite un metodo di azione a cui viene applicata l'autorizzazione e restituisci un oggetto FileResult.
[Authorize]
public IActionResult BannerImage()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
Esplorazione cartella
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
, richieste a una cartella nella ricerca in wwwroot
:
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 delle 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();
});
}
Considera la seguente gerarchia di directory:
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
.
Utilizzando la gerarchia di file e il codice precedente, gli URL si risolvono come segue:
URI | Risposta |
---|---|
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 eseguono un reindirizzamento lato client dall'URI di destinazione senza barra finale /
all'URI di destinazione con barra 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 la navigazione della directory, viene visualizzato un collegamento al file nell'elenco della 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
sono impostati di default sul 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. Si consiglia vivamente di disabilitare la navigazione tra directory in 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.