Statische Dateien in ASP.NET Core
Hinweis
Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Warnung
Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der Supportrichtlinie für .NET und .NET Core. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Wichtig
Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.
Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Von Rick Anderson
Bei statischen Dateien wie HTML, CSS, Images und JavaScript handelt es sich um Objekte, die Clients von einer ASP.NET Core-App standardmäßig direkt bereitgestellt werden.
Anleitungen zu statischen Dateien in Blazor, die die Anleitungen in diesem Artikel ergänzen oder ersetzen, finden Sie unter Statische Dateien in ASP.NET Core Blazor.
Bereitstellen statischer Dateien
Statische Dateien werden im Webstammverzeichnis des Projekts gespeichert. Das Standardverzeichnis lautet {content root}/wwwroot
, kann jedoch mit der Methode UseWebRoot geändert werden. Weitere Informationen finden Sie unter Inhaltsstammverzeichnis und Webstammverzeichnis.
Die Methode CreateBuilder legt das Inhaltsstammverzeichnis auf das aktuelle Verzeichnis fest:
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();
Auf statische Dateien kann über einen Pfad relativ zum Webstammverzeichnis zugegriffen werden. Die Webanwendung-Projektvorlagen verfügen beispielsweise über mehrere Ordner innerhalb des Ordners wwwroot
:
wwwroot
css
js
lib
Betrachten Sie eine App mit der wwwroot/images/MyImage.jpg
-Datei. Das URI-Format für den Zugriff auf eine Datei im images
-Ordner ist https://<hostname>/images/<image_file_name>
. Beispiel: https://localhost:5001/images/MyImage.jpg
MapStaticAssets
Das Erstellen von leistungsfähigen Web-Apps erfordert die Optimierung der Ressourcenübermittlung an den Browser. Mögliche Optimierungen sind:
- Eine bestimmte Ressource wird einmal bereitgestellt, bis sich die Datei ändert oder der Browser seinen Cache leert. Legen Sie den ETag-Header fest.
- Es wird verhindert, dass der Browser alte oder veraltete Ressourcen verwendet, nachdem eine Anwendung aktualisiert wurde. Legen Sie den Header Zuletzt geändert fest.
- Legen Sie den richtigen Zwischenspeicherungsheader fest.
- Verwenden Sie die Zwischenspeicherungs-Middleware.
- Stellen Sie wenn möglich komprimierte Versionen der Ressourcen bereit.
- Verwenden Sie einen CDN, um die Ressourcen näher an die Benutzerin oder den Benutzer zu bringen.
- Es minimiert die Größe der Ressourcen, die dem Browser zur Verfügung gestellt werden. Diese Optimierung beinhaltet keine Minimierung.
MapStaticAssets
ist eine Middleware, welche die Übermittlung statischer Objekte in einer App optimiert. Sie ist für alle UI-Frameworks geeignet, einschließlich Blazor, Razor Pages und MVC.
UseStaticFiles
dient auch statischen Dateien, bietet aber nicht das gleiche Maß an Optimierung wie MapStaticAssets
. Einen Vergleich von UseStaticFiles
und MapStaticAssets
finden Sie unter Optimierung der Bereitstellung statischer Web-Assets .
Verarbeiten von Dateien im Webstammverzeichnis
Mit den Standard-Webappvorlagen wird die MapStaticAssets
-Methode in Program.cs
aufgerufen, die die Verarbeitung statischer Dateien ermöglicht:
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();
Die parameterlose Überladung der Methode UseStaticFiles
markiert die Dateien im Webstammverzeichnis als bereitstellbar. Folgendes Markup verweist auf wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Im vorstehenden Markup verweist die Tilde (~
) auf den Webstamm.
Bereitstellen von Dateien außerhalb des Webstammverzeichnisses
Erwägen Sie eine Verzeichnishierarchie, bei der sich die bereitzustellenden statischen Dateien außerhalb des Webstammverzeichnisses befinden:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Über eine Anforderung kann auf die Datei red-rose.jpg
zugegriffen werden, indem die Middleware für statische Dateien wie folgt konfiguriert wird:
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();
Im vorangehenden Code wird die MyStaticFiles-Verzeichnishierarchie öffentlich über das URI-Segment StaticFiles verfügbar gemacht. Eine Anforderung an https://<hostname>/StaticFiles/images/red-rose.jpg
dient der red-rose.jpg
-Datei.
Folgendes Markup verweist auf MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Informationen zum Verarbeiten von Dateien aus mehreren Speicherorten finden Sie unter Bereitstellen von Dateien aus mehreren Speicherorten.
Festlegen von HTTP-Antwortheadern
Mit einem StaticFileOptions-Objekt können HTTP-Antwortheader festgelegt werden. Neben der Konfiguration statischer, über den Webstamm bereitgestellter Dateien wird mit dem folgenden Code der Cache-Control-Header festgelegt:
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();
Der vorangehende Code macht statische Dateien im lokalen Cache eine Woche lang öffentlich zugänglich.
Autorisierung statischer Dateien
Die ASP.NET Core-Vorlagen rufen MapStaticAssets
vor UseAuthorization auf. Die meisten Apps folgen diesem Muster. Wenn die Middleware für statische Dateien vor der Autorisierungsmiddleware aufgerufen wird, gilt Folgendes:
- In den statischen Dateien werden keine Autorisierungsüberprüfungen durchgeführt.
- Statische Dateien, die von der Middleware für statische Dateien bereitgestellt werden – wie beispielsweise diejenigen unter
wwwroot
– sind öffentlich zugänglich.
So stellen Sie statische Dateien basierend auf Autorisierung bereit:
- Speichern Sie sie außerhalb von
wwwroot
. - Rufen Sie
UseStaticFiles
nach dem Aufruf vonUseAuthorization
auf, und geben Sie einen Pfad an. - Legen Sie die Autorisierungsrichtlinie für Fallbacks fest.
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();
Im vorstehenden Code erfordert die Richtlinie für die Fallbackautorisierung, dass alle Benutzer authentifiziert werden müssen. Endpunkte wie Controller, Razor Pages usw., die eigene Autorisierungsanforderungen angeben, verwenden die Autorisierungsrichtlinie für Fallbacks nicht. Beispielsweise verwenden Razor Pages, Controller oder Aktionsmethoden mit [AllowAnonymous]
oder [Authorize(PolicyName="MyPolicy")]
das angewendete Autorisierungsattribut anstelle der Autorisierungsrichtlinie für Fallbacks.
RequireAuthenticatedUser fügt der aktuellen Instanz DenyAnonymousAuthorizationRequirement hinzu. Dadurch wird die Authentifizierung des aktuellen Benutzers erzwungen.
Statische Ressourcen unter wwwroot
sind öffentlich zugänglich, weil die Middleware für statische Dateien (app.UseStaticFiles();
) vor UseAuthentication
aufgerufen wird. Statische Ressourcen im MyStaticFiles-Ordner erfordern eine Authentifizierung. Dies wird im Beispielcode veranschaulicht.
Eine Alternative zum Bereitstellen von Dateien basierend auf Autorisierung ist folgendes Verfahren:
Speichern Sie sie außerhalb von
wwwroot
sowie außerhalb sämtlicher Verzeichnisse, auf die die Middleware für statische Dateien zugreifen kann.Stellen Sie sie über eine Aktionsmethode bereit, für die die Autorisierung gilt, und geben Sie ein FileResult-Objekt zurück:
[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"); } }
Für den vorherigen Ansatz ist eine Seite oder ein Endpunkt pro Datei erforderlich. Der folgende Code gibt Dateien zurück oder lädt Dateien für authentifizierte Benutzer*innen hoch:
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 in dem vorangegangenen Beispiel verwendet einen Speicherpuffer für das Hochladen. Für die Verarbeitung großer Dateien verwenden Sie Streaming. Siehe Hochladen von großen Dateien mittels Streaming.
Das vollständige Beispiel finden Sie im GitHub-Ordner StaticFileAuth.
Verzeichnissuche
Die Verzeichnissuche ermöglicht die Verzeichnisauflistung in angegebenen Verzeichnissen.
Die Verzeichnissuche ist aus Sicherheitsgründen standardmäßig deaktiviert. Weitere Informationen finden Sie unter Sicherheitsüberlegungen für statische Dateien.
Aktivieren Sie die Verzeichnissuche mit AddDirectoryBrowser und 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();
Der vorangehende Code ermöglicht die Verzeichnissuche im Ordner wwwroot/images über die URL https://<hostname>/MyImages
mit Links zu den einzelnen Dateien und Ordnern:
AddDirectoryBrowser
fügt Dienste hinzu, die von der Middleware für die Verzeichnissuche benötigt werden, einschließlich HtmlEncoder. Diese Dienste können auch mit anderen Aufrufen hinzugefügt werden, z. B. AddRazorPages, aber wir empfehlen den Aufruf von AddDirectoryBrowser
, um sicherzustellen, dass die Dienste in allen Apps hinzugefügt werden.
Bereitstellen von Standarddokumenten
Durch das Festlegen einer Standardseite wird Besuchern ein Ausgangspunkt auf einer Website bereitgestellt. Rufen Sie die UseDefaultFiles-Methode auf, um eine Standarddatei aus wwwroot
zu stellen, ohne dass die Anforderungs-URL im Dateinamen enthalten sein muss:
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
muss vor UseStaticFiles
aufgerufen werden, damit die Standarddatei bereitgestellt wird. UseDefaultFiles
ist ein URL-Rewriter, der die Datei nicht verarbeiten kann.
Bei UseDefaultFiles
werden bei Anforderungen an einen Ordner in wwwroot
folgende Dateien durchsucht:
default.htm
default.html
index.htm
index.html
Die erste in der Liste gefundene Datei wird bereitgestellt, als wäre die Anforderung im Dateinamen enthalten. Die Browser-URL spiegelt weiterhin den angeforderten URI wider. In der Beispielanwendung wird zum Beispiel bei einer Anfrage an https://localhost:<port>/def/
default.html
von wwwroot/def
bedient.
Mit dem folgenden Code wird der Standarddateiname in mydefault.html
geändert:
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 für Standarddokumente
In UseFileServer werden die Funktionen von UseStaticFiles
, UseDefaultFiles
und (optional) UseDirectoryBrowser
miteinander kombiniert.
Rufen Sie app.UseFileServer
auf, um die Bereitstellung statischer Dateien und der Standarddatei zu aktivieren. Die Verzeichnissuche ist nicht aktiviert:
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();
Mit dem folgenden Code wird die Bereitstellung statischer Dateien, der Standarddatei und der Verzeichnissuche aktiviert:
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();
Betrachten Sie die folgende Verzeichnishierarchie:
wwwroot
css
images
js
MyStaticFiles
defaultFiles
default.html
image3.png
images
MyImage.jpg
Mit dem folgenden Code wird die Bereitstellung statischer Dateien, der Standarddatei und der Verzeichnissuche von MyStaticFiles
aktiviert:
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 muss aufgerufen werden, wenn der EnableDirectoryBrowsing
-Eigenschaftswert true
lautet.
Unter Verwendung der vorstehenden Dateihierarchie und des vorangehenden Codes werden URLs wie folgt aufgelöst:
URI | Antwort |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
Verzeichnisauflistung |
https://<hostname>/StaticFiles/defaultFiles |
MyStaticFiles/defaultFiles/default.html |
https://<hostname>/StaticFiles/defaultFiles/image3.png |
MyStaticFiles/defaultFiles//image3.png |
Wenn im Verzeichnis MyStaticFiles keine Datei mit Standardnamen vorhanden ist, gibt https://<hostname>/StaticFiles
die Verzeichnisliste mit klickbaren Links zurück:
UseDefaultFiles und UseDirectoryBrowser führen eine clientseitige Umleitung vom Ziel-URI ohne nachgestellten /
zum Ziel-URI mit nachgestelltem /
durch. Beispielsweise von https://<hostname>/StaticFiles
zu https://<hostname>/StaticFiles/
. Relative URLs im Verzeichnis StaticFiles gelten ohne nachstehenden Schrägstrich (/
) als ungültig, sofern nicht die RedirectToAppendTrailingSlash-Option von DefaultFilesOptions verwendet wird.
FileExtensionContentTypeProvider
Die FileExtensionContentTypeProvider-Klasse enthält eine Zuordnungs-Eigenschaft, die als Zuordnung von Dateierweiterungen zu MIME-Inhaltstypen dient. Im folgenden Beispiel werden mehrere Dateierweiterungen bekannten MIME-Typen zugeordnet. Die Erweiterung .rtf wird ersetzt, und .mp4 wird entfernt:
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();
Weitere Informationen finden Sie unter MIME-Inhaltstypen.
Inhaltstypen, die vom Standard abweichen
Die Middleware für statische Dateien erkennt fast 400 bekannte Dateiinhaltstypen. Wenn ein Benutzer eine Datei mit einem unbekannten Dateityp anfordert, übergibt die Middleware für statische Dateien die Anforderung an die nächste Middleware in der Pipeline. Wenn keine Middleware die Anforderung verarbeitet, wird die Meldung 404 Nicht gefunden zurückgegeben. Wenn die Verzeichnissuche aktiviert ist, wird ein Link zur Datei in einer Verzeichnisliste angezeigt.
Mit dem folgenden Code wird die Bereitstellung unbekannter Typen aktiviert und die unbekannte Datei als Image gerendert:
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();
Mit dem vorangehenden Code wird eine Anforderung für eine Datei mit unbekanntem Inhaltstyp als Image zurückgegeben.
Warnung
Die Aktivierung von ServeUnknownFileTypes stellt ein Sicherheitsrisiko dar. Diese Eigenschaft ist standardmäßig deaktiviert, von einer Verwendung wird abgeraten. FileExtensionContentTypeProvider bietet eine sicherere Alternative für die Bereitstellung von Dateien mit vom Standard abweichenden Erweiterungen.
Bereitstellen von Dateien aus mehreren Speicherorten
Beachten Sie die folgende Razor Seite, welche die /MyStaticFiles/image3.png
Datei anzeigt:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
Bei UseStaticFiles
und UseFileServer
zeigt der Dateianbieter standardmäßig auf wwwroot
. Weitere Instanzen von UseStaticFiles
und UseFileServer
können mit anderen Dateianbietern bereitgestellt werden, um Dateien von anderen Speicherorten bereitzustellen. Das folgende Beispiel ruft UseStaticFiles
zweimal auf, um Dateien aus wwwroot
und MyStaticFiles
zu verarbeiten:
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Unter Verwendung des vorherigen Codes:
- Die
/MyStaticFiles/image3.png
Datei wird angezeigt. - Die Bildtag-Hilfsprogramme AppendVersion werden nicht angewendet, da die Tag-Hilfsprogramme abhängig von WebRootFileProvider sind.
WebRootFileProvider
wurde nicht aktualisiert, denMyStaticFiles
Ordner zu beinhalten.
Der folgende Code aktualisiert WebRootFileProvider
, wodurch das Bildtag-Hilfsprogramm eine Version bereitstellen kann:
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();
Hinweis
Der zuvor beschriebene Ansatz gilt für Razor Pages und MVC-Apps. Anleitungen, die für Blazor Web App gelten, finden Sie unter Statische Dateien in ASP.NET Core-Blazor.
Sicherheitsüberlegungen für statische Dateien
Warnung
UseDirectoryBrowser
und UseStaticFiles
können Geheimnisse preisgeben. Eine Deaktivierung der Verzeichnissuche in der Produktionsumgebung wird dringend empfohlen. Überprüfen Sie sorgfältig, welche Verzeichnisse über UseStaticFiles
oder UseDirectoryBrowser
aktiviert wurden. Das gesamte Verzeichnis und die zugehörigen Unterverzeichnisse werden öffentlich zugänglich gemacht. Speichern Sie Dateien, die für eine Bereitstellung in der Öffentlichkeit geeignet sind, in einem dafür vorgesehenen Verzeichnis wie z.B. <content_root>/wwwroot
. Trennen Sie diese Dateien von MVC-Ansichten, Razor Pages, Konfigurationsdateien usw.
Die URLs für Inhalte, die mit
UseDirectoryBrowser
,UseStaticFiles
undMapStaticAssets
angezeigt werden, unterliegen der Groß-/Kleinschreibung und den Zeichenbeschränkungen des zugrunde liegenden Dateisystems. Bei Windows wird die Groß-/Kleinschreibung beispielsweise nicht beachtet, jedoch bei macOS und Linux.In IIS gehostete ASP.NET Core-Apps leiten über das ASP.NET Core-Modul alle Anforderungen an die App weiter, darunter die Anforderungen von statischen Dateien. Der IIS-Handler für statische Dateien wird nicht verwendet und hat keine Möglichkeit, Anforderungen zu verarbeiten.
Führen Sie im IIS-Manager die folgenden Schritte aus, um den statischen IIS-Dateihandler auf Server- oder Website-Ebene zu entfernen:
- Navigieren Sie zum Feature Module.
- Wählen Sie StaticFileModule aus der Liste aus.
- Klicken Sie in der Randleiste Aktionen auf Entfernen.
Warnung
Wenn der statische IIS-Dateihandler aktiviert ist und das ASP.NET Core-Modul falsch konfiguriert wurde, werden statische Dateien bereitgestellt. Dies geschieht beispielsweise, wenn die Datei web.config nicht bereitgestellt worden ist.
- Platzieren Sie Codedateien einschließlich
.cs
und.cshtml
außerhalb des Webstammverzeichnisses des App-Projekts. Aus diesem Grund wird eine logische Trennung zwischen den clientseitigen Inhalten der App und dem serverbasierten Code erschaffen. Dadurch wird verhindert, dass serverseitiger Code aufgedeckt wird.
Bedienen Sie Dateien außerhalb von wwwroot, indem Sie IWebHostEnvironment.WebRootPath aktualisieren
Wenn IWebHostEnvironment.WebRootPath auf einen anderen Ordner als wwwroot
festgelegt ist:
- In der Entwicklungsumgebung werden statische Ressourcen, die sich sowohl unter
wwwroot
als auch dem aktualisiertenIWebHostEnvironment.WebRootPath
befinden, vonwwwroot
bedient. - In jeder anderen Umgebung als der Entwicklungsumgebung werden doppelt vorhandene statische Ressourcen aus dem aktualisierten
IWebHostEnvironment.WebRootPath
-Ordner bereitgestellt.
Betrachten Sie eine Web-App, die mit der leeren Webvorlage erstellt wurde:
Sie enthält eine Datei
Index.html
inwwwroot
undwwwroot-custom
.Mit der folgenden aktualisierten
Program.cs
-Datei, dieWebRootPath = "wwwroot-custom"
festlegt: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();
Im vorhergehenden Code bewirken Anforderungen an /
Folgendes:
- In der Entwicklungsumgebung wird
wwwroot/Index.html
zurückgegeben - In jeder anderen Umgebung als der Entwicklungsumgebung wird
wwwroot-custom/Index.html
zurückgegeben
Verwenden Sie eine der folgenden Ansätze, um sicherzustellen, dass Ressourcen aus wwwroot-custom
zurückgegeben werden:
Löschen Sie doppelte benannte Ressourcen in
wwwroot
.Legen Sie
"ASPNETCORE_ENVIRONMENT"
inProperties/launchSettings.json
auf einen beliebigen anderen Wert als"Development"
fest.Deaktivieren Sie statische Webressourcen vollständig, indem Sie
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
in der Projektdatei festlegen. WARNUNG: Durch das Deaktivieren statischer Webressourcen werden die Razor-Klassenbibliotheken deaktiviert.Fügen Sie der Projektdatei die folgende XML hinzu:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
Der folgende Code aktualisiert IWebHostEnvironment.WebRootPath
auf einen nicht auf die Entwicklung bezogenen Wert, der garantiert, dass doppelte Inhalte aus wwwroot-custom
anstelle von wwwroot
zurückgegeben werden:
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();
Zusätzliche Ressourcen
Von Rick Anderson
Bei statischen Dateien wie HTML, CSS, Images und JavaScript handelt es sich um Objekte, die Clients von einer ASP.NET Core-App standardmäßig direkt bereitgestellt werden.
Bereitstellen statischer Dateien
Statische Dateien werden im Webstammverzeichnis des Projekts gespeichert. Das Standardverzeichnis lautet {content root}/wwwroot
, kann jedoch mit der Methode UseWebRoot geändert werden. Weitere Informationen finden Sie unter Inhaltsstammverzeichnis und Webstammverzeichnis.
Die Methode CreateBuilder legt das Inhaltsstammverzeichnis auf das aktuelle Verzeichnis fest:
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();
Auf statische Dateien kann über einen Pfad relativ zum Webstammverzeichnis zugegriffen werden. Die Webanwendung-Projektvorlagen verfügen beispielsweise über mehrere Ordner innerhalb des Ordners wwwroot
:
wwwroot
css
js
lib
Erstellen Sie ggf. den wwwroot/images-Ordner, und fügen Sie die Datei wwwroot/images/MyImage.jpg
hinzu. Das URI-Format für den Zugriff auf eine Datei im images
-Ordner ist https://<hostname>/images/<image_file_name>
. Beispiel: https://localhost:5001/images/MyImage.jpg
Verarbeiten von Dateien im Webstammverzeichnis
Mit den Standard-Webappvorlagen wird die UseStaticFiles-Methode in Program.cs
aufgerufen, die die Verarbeitung statischer Dateien ermöglicht:
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();
Die parameterlose Überladung der Methode UseStaticFiles
markiert die Dateien im Webstammverzeichnis als bereitstellbar. Folgendes Markup verweist auf wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Im vorstehenden Markup verweist die Tilde (~
) auf den Webstamm.
Bereitstellen von Dateien außerhalb des Webstammverzeichnisses
Erwägen Sie eine Verzeichnishierarchie, bei der sich die bereitzustellenden statischen Dateien außerhalb des Webstammverzeichnisses befinden:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Über eine Anforderung kann auf die Datei red-rose.jpg
zugegriffen werden, indem die Middleware für statische Dateien wie folgt konfiguriert wird:
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();
Im vorangehenden Code wird die MyStaticFiles-Verzeichnishierarchie öffentlich über das URI-Segment StaticFiles verfügbar gemacht. Eine Anforderung an https://<hostname>/StaticFiles/images/red-rose.jpg
dient der red-rose.jpg
-Datei.
Folgendes Markup verweist auf MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Informationen zum Verarbeiten von Dateien aus mehreren Speicherorten finden Sie unter Bereitstellen von Dateien aus mehreren Speicherorten.
Festlegen von HTTP-Antwortheadern
Mit einem StaticFileOptions-Objekt können HTTP-Antwortheader festgelegt werden. Neben der Konfiguration statischer, über den Webstamm bereitgestellter Dateien wird mit dem folgenden Code der Cache-Control-Header festgelegt:
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();
Der vorstehende Code macht statische Dateien im lokalen Cache eine Woche lang (604800 Sekunden) öffentlich zugänglich.
Autorisierung statischer Dateien
Die ASP.NET Core-Vorlagen rufen UseStaticFiles vor UseAuthorization auf. Die meisten Apps folgen diesem Muster. Wenn die Middleware für statische Dateien vor der Autorisierungsmiddleware aufgerufen wird, gilt Folgendes:
- In den statischen Dateien werden keine Autorisierungsüberprüfungen durchgeführt.
- Statische Dateien, die von der Middleware für statische Dateien bereitgestellt werden – wie beispielsweise diejenigen unter
wwwroot
– sind öffentlich zugänglich.
So stellen Sie statische Dateien basierend auf Autorisierung bereit:
- Speichern Sie sie außerhalb von
wwwroot
. - Rufen Sie
UseStaticFiles
nach dem Aufruf vonUseAuthorization
auf, und geben Sie einen Pfad an. - Legen Sie die Autorisierungsrichtlinie für Fallbacks fest.
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();
Im vorstehenden Code erfordert die Richtlinie für die Fallbackautorisierung, dass alle Benutzer authentifiziert werden müssen. Endpunkte wie Controller, Razor Pages usw., die eigene Autorisierungsanforderungen angeben, verwenden die Autorisierungsrichtlinie für Fallbacks nicht. Beispielsweise verwenden Razor Pages, Controller oder Aktionsmethoden mit [AllowAnonymous]
oder [Authorize(PolicyName="MyPolicy")]
das angewendete Autorisierungsattribut anstelle der Autorisierungsrichtlinie für Fallbacks.
RequireAuthenticatedUser fügt der aktuellen Instanz DenyAnonymousAuthorizationRequirement hinzu. Dadurch wird die Authentifizierung des aktuellen Benutzers erzwungen.
Statische Ressourcen unter wwwroot
sind öffentlich zugänglich, weil die Middleware für statische Dateien (app.UseStaticFiles();
) vor UseAuthentication
aufgerufen wird. Statische Ressourcen im MyStaticFiles-Ordner erfordern eine Authentifizierung. Dies wird im Beispielcode veranschaulicht.
Eine Alternative zum Bereitstellen von Dateien basierend auf Autorisierung ist folgendes Verfahren:
Speichern Sie sie außerhalb von
wwwroot
sowie außerhalb sämtlicher Verzeichnisse, auf die die Middleware für statische Dateien zugreifen kann.Stellen Sie sie über eine Aktionsmethode bereit, für die die Autorisierung gilt, und geben Sie ein FileResult-Objekt zurück:
[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"); } }
Für den vorherigen Ansatz ist eine Seite oder ein Endpunkt pro Datei erforderlich. Der folgende Code gibt Dateien zurück oder lädt Dateien für authentifizierte Benutzer*innen hoch:
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();
Das vollständige Beispiel finden Sie im GitHub-Ordner StaticFileAuth.
Verzeichnissuche
Die Verzeichnissuche ermöglicht die Verzeichnisauflistung in angegebenen Verzeichnissen.
Die Verzeichnissuche ist aus Sicherheitsgründen standardmäßig deaktiviert. Weitere Informationen finden Sie unter Sicherheitsüberlegungen für statische Dateien.
Aktivieren Sie die Verzeichnissuche mit AddDirectoryBrowser und 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();
Der vorangehende Code ermöglicht die Verzeichnissuche im Ordner wwwroot/images über die URL https://<hostname>/MyImages
mit Links zu den einzelnen Dateien und Ordnern:
AddDirectoryBrowser
fügt Dienste hinzu, die von der Middleware für die Verzeichnissuche benötigt werden, einschließlich HtmlEncoder. Diese Dienste können auch mit anderen Aufrufen hinzugefügt werden, z. B. AddRazorPages, aber wir empfehlen den Aufruf von AddDirectoryBrowser
, um sicherzustellen, dass die Dienste in allen Apps hinzugefügt werden.
Bereitstellen von Standarddokumenten
Durch das Festlegen einer Standardseite wird Besuchern ein Ausgangspunkt auf einer Website bereitgestellt. Rufen Sie die UseDefaultFiles-Methode auf, um eine Standarddatei aus wwwroot
zu stellen, ohne dass die Anforderungs-URL im Dateinamen enthalten sein muss:
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
muss vor UseStaticFiles
aufgerufen werden, damit die Standarddatei bereitgestellt wird. UseDefaultFiles
ist ein URL-Rewriter, der die Datei nicht verarbeiten kann.
Bei UseDefaultFiles
werden bei Anforderungen an einen Ordner in wwwroot
folgende Dateien durchsucht:
default.htm
default.html
index.htm
index.html
Die erste in der Liste gefundene Datei wird bereitgestellt, als wäre die Anforderung im Dateinamen enthalten. Die Browser-URL spiegelt weiterhin den angeforderten URI wider.
Mit dem folgenden Code wird der Standarddateiname in mydefault.html
geändert:
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 für Standarddokumente
In UseFileServer werden die Funktionen von UseStaticFiles
, UseDefaultFiles
und (optional) UseDirectoryBrowser
miteinander kombiniert.
Rufen Sie app.UseFileServer
auf, um die Bereitstellung statischer Dateien und der Standarddatei zu aktivieren. Die Verzeichnissuche ist nicht aktiviert:
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();
Mit dem folgenden Code wird die Bereitstellung statischer Dateien, der Standarddatei und der Verzeichnissuche aktiviert:
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();
Betrachten Sie die folgende Verzeichnishierarchie:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
Mit dem folgenden Code wird die Bereitstellung statischer Dateien, der Standarddatei und der Verzeichnissuche von MyStaticFiles
aktiviert:
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 muss aufgerufen werden, wenn der EnableDirectoryBrowsing
-Eigenschaftswert true
lautet.
Unter Verwendung der vorstehenden Dateihierarchie und des vorangehenden Codes werden URLs wie folgt aufgelöst:
URI | Antwort |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Wenn im Verzeichnis MyStaticFiles keine Datei mit Standardnamen vorhanden ist, gibt https://<hostname>/StaticFiles
die Verzeichnisliste mit klickbaren Links zurück:
UseDefaultFiles und UseDirectoryBrowser führen eine clientseitige Umleitung vom Ziel-URI ohne nachgestellten /
zum Ziel-URI mit nachgestelltem /
durch. Beispielsweise von https://<hostname>/StaticFiles
zu https://<hostname>/StaticFiles/
. Relative URLs im Verzeichnis StaticFiles gelten ohne nachstehenden Schrägstrich (/
) als ungültig, sofern nicht die RedirectToAppendTrailingSlash-Option von DefaultFilesOptions verwendet wird.
FileExtensionContentTypeProvider
Die Klasse FileExtensionContentTypeProvider enthält eine Mappings
-Eigenschaft, die als Zuordnung von Dateierweiterungen zu MIME-Inhaltstypen dient. Im folgenden Beispiel werden mehrere Dateierweiterungen bekannten MIME-Typen zugeordnet. Die Erweiterung .rtf wird ersetzt, und .mp4 wird entfernt:
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();
Weitere Informationen finden Sie unter MIME-Inhaltstypen.
Inhaltstypen, die vom Standard abweichen
Die Middleware für statische Dateien erkennt fast 400 bekannte Dateiinhaltstypen. Wenn ein Benutzer eine Datei mit einem unbekannten Dateityp anfordert, übergibt die Middleware für statische Dateien die Anforderung an die nächste Middleware in der Pipeline. Wenn keine Middleware die Anforderung verarbeitet, wird die Meldung 404 Nicht gefunden zurückgegeben. Wenn die Verzeichnissuche aktiviert ist, wird ein Link zur Datei in einer Verzeichnisliste angezeigt.
Mit dem folgenden Code wird die Bereitstellung unbekannter Typen aktiviert und die unbekannte Datei als Image gerendert:
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();
Mit dem vorangehenden Code wird eine Anforderung für eine Datei mit unbekanntem Inhaltstyp als Image zurückgegeben.
Warnung
Die Aktivierung von ServeUnknownFileTypes stellt ein Sicherheitsrisiko dar. Diese Eigenschaft ist standardmäßig deaktiviert, von einer Verwendung wird abgeraten. FileExtensionContentTypeProvider bietet eine sicherere Alternative für die Bereitstellung von Dateien mit vom Standard abweichenden Erweiterungen.
Bereitstellen von Dateien aus mehreren Speicherorten
Beachten Sie die folgende Razor Seite, welche die /MyStaticFiles/image3.png
Datei anzeigt:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
Bei UseStaticFiles
und UseFileServer
zeigt der Dateianbieter standardmäßig auf wwwroot
. Weitere Instanzen von UseStaticFiles
und UseFileServer
können mit anderen Dateianbietern bereitgestellt werden, um Dateien von anderen Speicherorten bereitzustellen. Das folgende Beispiel ruft UseStaticFiles
zweimal auf, um Dateien aus wwwroot
und MyStaticFiles
zu verarbeiten:
app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Unter Verwendung des vorherigen Codes:
- Die
/MyStaticFiles/image3.png
Datei wird angezeigt. - Die Bildtag-Hilfsprogramme AppendVersion werden nicht angewendet, da die Tag-Hilfsprogramme abhängig von WebRootFileProvider sind.
WebRootFileProvider
wurde nicht aktualisiert, denMyStaticFiles
Ordner zu beinhalten.
Der folgende Code aktualisiert WebRootFileProvider
, wodurch das Bildtag-Hilfsprogramm eine Version bereitstellen kann:
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();
Hinweis
Der zuvor beschriebene Ansatz gilt für Razor Pages und MVC-Apps. Anleitungen, die für Blazor Web App gelten, finden Sie unter Statische Dateien in ASP.NET Core-Blazor.
Sicherheitsüberlegungen für statische Dateien
Warnung
UseDirectoryBrowser
und UseStaticFiles
können Geheimnisse aufdecken. Eine Deaktivierung der Verzeichnissuche in der Produktionsumgebung wird dringend empfohlen. Überprüfen Sie sorgfältig, welche Verzeichnisse über UseStaticFiles
oder UseDirectoryBrowser
aktiviert wurden. Das gesamte Verzeichnis und die zugehörigen Unterverzeichnisse werden öffentlich zugänglich gemacht. Speichern Sie Dateien, die für eine Bereitstellung in der Öffentlichkeit geeignet sind, in einem dafür vorgesehenen Verzeichnis wie z.B. <content_root>/wwwroot
. Trennen Sie diese Dateien von MVC-Ansichten, Razor Pages, Konfigurationsdateien usw.
Die URLs für Inhalte, die mit
UseDirectoryBrowser
undUseStaticFiles
verfügbar gemacht wurden, unterliegen der Groß-/Kleinschreibung und den Zeichenbeschränkungen des zugrunde liegenden Dateisystems. Bei Windows wird die Groß-/Kleinschreibung beispielsweise nicht beachtet, jedoch bei macOS und Linux.In IIS gehostete ASP.NET Core-Apps leiten über das ASP.NET Core-Modul alle Anforderungen an die App weiter, darunter die Anforderungen von statischen Dateien. Der IIS-Handler für statische Dateien wird nicht verwendet und hat keine Möglichkeit, Anforderungen zu verarbeiten.
Führen Sie im IIS-Manager die folgenden Schritte aus, um den statischen IIS-Dateihandler auf Server- oder Website-Ebene zu entfernen:
- Navigieren Sie zum Feature Module.
- Wählen Sie StaticFileModule aus der Liste aus.
- Klicken Sie in der Randleiste Aktionen auf Entfernen.
Warnung
Wenn der statische IIS-Dateihandler aktiviert ist und das ASP.NET Core-Modul falsch konfiguriert wurde, werden statische Dateien bereitgestellt. Dies geschieht beispielsweise, wenn die Datei web.config nicht bereitgestellt worden ist.
- Platzieren Sie Codedateien einschließlich
.cs
und.cshtml
außerhalb des Webstammverzeichnisses des App-Projekts. Aus diesem Grund wird eine logische Trennung zwischen den clientseitigen Inhalten der App und dem serverbasierten Code erschaffen. Dadurch wird verhindert, dass serverseitiger Code aufgedeckt wird.
Bedienen Sie Dateien außerhalb von wwwroot, indem Sie IWebHostEnvironment.WebRootPath aktualisieren
Wenn IWebHostEnvironment.WebRootPath auf einen anderen Ordner als wwwroot
festgelegt ist:
- In der Entwicklungsumgebung werden statische Ressourcen, die sich sowohl unter
wwwroot
als auch dem aktualisiertenIWebHostEnvironment.WebRootPath
befinden, vonwwwroot
bedient. - In jeder anderen Umgebung als der Entwicklungsumgebung werden doppelt vorhandene statische Ressourcen aus dem aktualisierten
IWebHostEnvironment.WebRootPath
-Ordner bereitgestellt.
Betrachten Sie eine Web-App, die mit der leeren Webvorlage erstellt wurde:
Sie enthält eine Datei
Index.html
inwwwroot
undwwwroot-custom
.Mit der folgenden aktualisierten
Program.cs
-Datei, dieWebRootPath = "wwwroot-custom"
festlegt: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();
Im vorhergehenden Code bewirken Anforderungen an /
Folgendes:
- In der Entwicklungsumgebung wird
wwwroot/Index.html
zurückgegeben - In jeder anderen Umgebung als der Entwicklungsumgebung wird
wwwroot-custom/Index.html
zurückgegeben
Verwenden Sie eine der folgenden Ansätze, um sicherzustellen, dass Ressourcen aus wwwroot-custom
zurückgegeben werden:
Löschen Sie doppelte benannte Ressourcen in
wwwroot
.Legen Sie
"ASPNETCORE_ENVIRONMENT"
inProperties/launchSettings.json
auf einen beliebigen anderen Wert als"Development"
fest.Deaktivieren Sie statische Webressourcen vollständig, indem Sie
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
in der Projektdatei festlegen. WARNUNG: Durch das Deaktivieren statischer Webressourcen werden die Razor-Klassenbibliotheken deaktiviert.Fügen Sie der Projektdatei den folgenden JSON-Code hinzu:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
Der folgende Code aktualisiert IWebHostEnvironment.WebRootPath
auf einen nicht auf die Entwicklung bezogenen Wert, der garantiert, dass doppelte Inhalte aus wwwroot-custom
anstelle von wwwroot
zurückgegeben werden:
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();
Zusätzliche Ressourcen
Von Rick Anderson und Kirk Larkin
Bei statischen Dateien wie HTML, CSS, Images und JavaScript handelt es sich um Objekte, die Clients von einer ASP.NET Core-App standardmäßig direkt bereitgestellt werden.
Bereitstellen statischer Dateien
Statische Dateien werden im Webstammverzeichnis des Projekts gespeichert. Das Standardverzeichnis lautet {content root}/wwwroot
, kann jedoch mit der Methode UseWebRoot geändert werden. Weitere Informationen finden Sie unter Inhaltsstammverzeichnis und Webstammverzeichnis.
Die Methode CreateBuilder legt das Inhaltsstammverzeichnis auf das aktuelle Verzeichnis fest:
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();
Auf statische Dateien kann über einen Pfad relativ zum Webstammverzeichnis zugegriffen werden. Die Webanwendung-Projektvorlagen verfügen beispielsweise über mehrere Ordner innerhalb des Ordners wwwroot
:
wwwroot
css
js
lib
Erstellen Sie ggf. den wwwroot/images-Ordner, und fügen Sie die Datei wwwroot/images/MyImage.jpg
hinzu. Das URI-Format für den Zugriff auf eine Datei im images
-Ordner ist https://<hostname>/images/<image_file_name>
. Beispiel: https://localhost:5001/images/MyImage.jpg
Verarbeiten von Dateien im Webstammverzeichnis
Mit den Standard-Webappvorlagen wird die UseStaticFiles-Methode in Program.cs
aufgerufen, die die Verarbeitung statischer Dateien ermöglicht:
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();
Die parameterlose Überladung der Methode UseStaticFiles
markiert die Dateien im Webstammverzeichnis als bereitstellbar. Folgendes Markup verweist auf wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Im vorstehenden Markup verweist die Tilde (~
) auf den Webstamm.
Bereitstellen von Dateien außerhalb des Webstammverzeichnisses
Erwägen Sie eine Verzeichnishierarchie, bei der sich die bereitzustellenden statischen Dateien außerhalb des Webstammverzeichnisses befinden:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Über eine Anforderung kann auf die Datei red-rose.jpg
zugegriffen werden, indem die Middleware für statische Dateien wie folgt konfiguriert wird:
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();
Im vorangehenden Code wird die MyStaticFiles-Verzeichnishierarchie öffentlich über das URI-Segment StaticFiles verfügbar gemacht. Eine Anforderung an https://<hostname>/StaticFiles/images/red-rose.jpg
dient der red-rose.jpg
-Datei.
Folgendes Markup verweist auf MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Informationen zum Verarbeiten von Dateien aus mehreren Speicherorten finden Sie unter Bereitstellen von Dateien aus mehreren Speicherorten.
Festlegen von HTTP-Antwortheadern
Mit einem StaticFileOptions-Objekt können HTTP-Antwortheader festgelegt werden. Neben der Konfiguration statischer, über den Webstamm bereitgestellter Dateien wird mit dem folgenden Code der Cache-Control-Header festgelegt:
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();
Der vorstehende Code macht statische Dateien im lokalen Cache eine Woche lang (604800 Sekunden) öffentlich zugänglich.
Autorisierung statischer Dateien
Die ASP.NET Core-Vorlagen rufen UseStaticFiles vor UseAuthorization auf. Die meisten Apps folgen diesem Muster. Wenn die Middleware für statische Dateien vor der Autorisierungsmiddleware aufgerufen wird, gilt Folgendes:
- In den statischen Dateien werden keine Autorisierungsüberprüfungen durchgeführt.
- Statische Dateien, die von der Middleware für statische Dateien bereitgestellt werden – wie beispielsweise diejenigen unter
wwwroot
– sind öffentlich zugänglich.
So stellen Sie statische Dateien basierend auf Autorisierung bereit:
- Speichern Sie sie außerhalb von
wwwroot
. - Rufen Sie
UseStaticFiles
nach dem Aufruf vonUseAuthorization
auf, und geben Sie einen Pfad an. - Legen Sie die Autorisierungsrichtlinie für Fallbacks fest.
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();
Im vorstehenden Code erfordert die Richtlinie für die Fallbackautorisierung, dass alle Benutzer authentifiziert werden müssen. Endpunkte wie Controller, Razor Pages usw., die eigene Autorisierungsanforderungen angeben, verwenden die Autorisierungsrichtlinie für Fallbacks nicht. Beispielsweise verwenden Razor Pages, Controller oder Aktionsmethoden mit [AllowAnonymous]
oder [Authorize(PolicyName="MyPolicy")]
das angewendete Autorisierungsattribut anstelle der Autorisierungsrichtlinie für Fallbacks.
RequireAuthenticatedUser fügt der aktuellen Instanz DenyAnonymousAuthorizationRequirement hinzu. Dadurch wird die Authentifizierung des aktuellen Benutzers erzwungen.
Statische Ressourcen unter wwwroot
sind öffentlich zugänglich, weil die Middleware für statische Dateien (app.UseStaticFiles();
) vor UseAuthentication
aufgerufen wird. Statische Ressourcen im MyStaticFiles-Ordner erfordern eine Authentifizierung. Dies wird im Beispielcode veranschaulicht.
Eine Alternative zum Bereitstellen von Dateien basierend auf Autorisierung ist folgendes Verfahren:
- Speichern Sie sie außerhalb von
wwwroot
sowie außerhalb sämtlicher Verzeichnisse, auf die die Middleware für statische Dateien zugreifen kann. - Stellen Sie sie über eine Aktionsmethode bereit, für die die Autorisierung gilt, und geben Sie ein FileResult-Objekt zurück:
[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");
}
}
Verzeichnissuche
Die Verzeichnissuche ermöglicht die Verzeichnisauflistung in angegebenen Verzeichnissen.
Die Verzeichnissuche ist aus Sicherheitsgründen standardmäßig deaktiviert. Weitere Informationen finden Sie unter Sicherheitsüberlegungen für statische Dateien.
Aktivieren Sie die Verzeichnissuche mit AddDirectoryBrowser und 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();
Der vorangehende Code ermöglicht die Verzeichnissuche im Ordner wwwroot/images über die URL https://<hostname>/MyImages
mit Links zu den einzelnen Dateien und Ordnern:
AddDirectoryBrowser
fügt Dienste hinzu, die von der Middleware für die Verzeichnissuche benötigt werden, einschließlich HtmlEncoder. Diese Dienste können auch mit anderen Aufrufen hinzugefügt werden, z. B. AddRazorPages, aber wir empfehlen den Aufruf von AddDirectoryBrowser
, um sicherzustellen, dass die Dienste in allen Apps hinzugefügt werden.
Bereitstellen von Standarddokumenten
Durch das Festlegen einer Standardseite wird Besuchern ein Ausgangspunkt auf einer Website bereitgestellt. Rufen Sie die UseDefaultFiles-Methode auf, um eine Standarddatei aus wwwroot
zu stellen, ohne dass die Anforderungs-URL im Dateinamen enthalten sein muss:
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
muss vor UseStaticFiles
aufgerufen werden, damit die Standarddatei bereitgestellt wird. UseDefaultFiles
ist ein URL-Rewriter, der die Datei nicht verarbeiten kann.
Bei UseDefaultFiles
werden bei Anforderungen an einen Ordner in wwwroot
folgende Dateien durchsucht:
default.htm
default.html
index.htm
index.html
Die erste in der Liste gefundene Datei wird bereitgestellt, als wäre die Anforderung im Dateinamen enthalten. Die Browser-URL spiegelt weiterhin den angeforderten URI wider.
Mit dem folgenden Code wird der Standarddateiname in mydefault.html
geändert:
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 für Standarddokumente
In UseFileServer werden die Funktionen von UseStaticFiles
, UseDefaultFiles
und (optional) UseDirectoryBrowser
miteinander kombiniert.
Rufen Sie app.UseFileServer
auf, um die Bereitstellung statischer Dateien und der Standarddatei zu aktivieren. Die Verzeichnissuche ist nicht aktiviert:
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();
Mit dem folgenden Code wird die Bereitstellung statischer Dateien, der Standarddatei und der Verzeichnissuche aktiviert:
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();
Betrachten Sie die folgende Verzeichnishierarchie:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
Mit dem folgenden Code wird die Bereitstellung statischer Dateien, der Standarddatei und der Verzeichnissuche von MyStaticFiles
aktiviert:
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 muss aufgerufen werden, wenn der EnableDirectoryBrowsing
-Eigenschaftswert true
lautet.
Unter Verwendung der vorstehenden Dateihierarchie und des vorangehenden Codes werden URLs wie folgt aufgelöst:
URI | Antwort |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Wenn im Verzeichnis MyStaticFiles keine Datei mit Standardnamen vorhanden ist, gibt https://<hostname>/StaticFiles
die Verzeichnisliste mit klickbaren Links zurück:
UseDefaultFiles und UseDirectoryBrowser führen eine clientseitige Umleitung vom Ziel-URI ohne nachgestellten /
zum Ziel-URI mit nachgestelltem /
durch. Beispielsweise von https://<hostname>/StaticFiles
zu https://<hostname>/StaticFiles/
. Relative URLs im Verzeichnis StaticFiles gelten ohne nachstehenden Schrägstrich (/
) als ungültig, sofern nicht die RedirectToAppendTrailingSlash-Option von DefaultFilesOptions verwendet wird.
FileExtensionContentTypeProvider
Die Klasse FileExtensionContentTypeProvider enthält eine Mappings
-Eigenschaft, die als Zuordnung von Dateierweiterungen zu MIME-Inhaltstypen dient. Im folgenden Beispiel werden mehrere Dateierweiterungen bekannten MIME-Typen zugeordnet. Die Erweiterung .rtf wird ersetzt, und .mp4 wird entfernt:
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();
Weitere Informationen finden Sie unter MIME-Inhaltstypen.
Inhaltstypen, die vom Standard abweichen
Die Middleware für statische Dateien erkennt fast 400 bekannte Dateiinhaltstypen. Wenn ein Benutzer eine Datei mit einem unbekannten Dateityp anfordert, übergibt die Middleware für statische Dateien die Anforderung an die nächste Middleware in der Pipeline. Wenn keine Middleware die Anforderung verarbeitet, wird die Meldung 404 Nicht gefunden zurückgegeben. Wenn die Verzeichnissuche aktiviert ist, wird ein Link zur Datei in einer Verzeichnisliste angezeigt.
Mit dem folgenden Code wird die Bereitstellung unbekannter Typen aktiviert und die unbekannte Datei als Image gerendert:
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();
Mit dem vorangehenden Code wird eine Anforderung für eine Datei mit unbekanntem Inhaltstyp als Image zurückgegeben.
Warnung
Die Aktivierung von ServeUnknownFileTypes stellt ein Sicherheitsrisiko dar. Diese Eigenschaft ist standardmäßig deaktiviert, von einer Verwendung wird abgeraten. FileExtensionContentTypeProvider bietet eine sicherere Alternative für die Bereitstellung von Dateien mit vom Standard abweichenden Erweiterungen.
Bereitstellen von Dateien aus mehreren Speicherorten
Beachten Sie die folgende Razor Seite, welche die /MyStaticFiles/image3.png
Datei anzeigt:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
Bei UseStaticFiles
und UseFileServer
zeigt der Dateianbieter standardmäßig auf wwwroot
. Weitere Instanzen von UseStaticFiles
und UseFileServer
können mit anderen Dateianbietern bereitgestellt werden, um Dateien von anderen Speicherorten bereitzustellen. Das folgende Beispiel ruft UseStaticFiles
zweimal auf, um Dateien aus wwwroot
und MyStaticFiles
zu verarbeiten:
app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Unter Verwendung des vorherigen Codes:
- Die
/MyStaticFiles/image3.png
Datei wird angezeigt. - Die Bildtag-Hilfsprogramme AppendVersion werden nicht angewendet, da die Tag-Hilfsprogramme abhängig von WebRootFileProvider sind.
WebRootFileProvider
wurde nicht aktualisiert, denMyStaticFiles
Ordner zu beinhalten.
Der folgende Code aktualisiert WebRootFileProvider
, wodurch das Bildtag-Hilfsprogramm eine Version bereitstellen kann:
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();
Sicherheitsüberlegungen für statische Dateien
Warnung
UseDirectoryBrowser
und UseStaticFiles
können Geheimnisse aufdecken. Eine Deaktivierung der Verzeichnissuche in der Produktionsumgebung wird dringend empfohlen. Überprüfen Sie sorgfältig, welche Verzeichnisse über UseStaticFiles
oder UseDirectoryBrowser
aktiviert wurden. Das gesamte Verzeichnis und die zugehörigen Unterverzeichnisse werden öffentlich zugänglich gemacht. Speichern Sie Dateien, die für eine Bereitstellung in der Öffentlichkeit geeignet sind, in einem dafür vorgesehenen Verzeichnis wie z.B. <content_root>/wwwroot
. Trennen Sie diese Dateien von MVC-Ansichten, Razor Pages, Konfigurationsdateien usw.
Die URLs für Inhalte, die mit
UseDirectoryBrowser
undUseStaticFiles
verfügbar gemacht wurden, unterliegen der Groß-/Kleinschreibung und den Zeichenbeschränkungen des zugrunde liegenden Dateisystems. Bei Windows wird die Groß-/Kleinschreibung beispielsweise nicht beachtet, jedoch bei macOS und Linux.In IIS gehostete ASP.NET Core-Apps leiten über das ASP.NET Core-Modul alle Anforderungen an die App weiter, darunter die Anforderungen von statischen Dateien. Der IIS-Handler für statische Dateien wird nicht verwendet und hat keine Möglichkeit, Anforderungen zu verarbeiten.
Führen Sie im IIS-Manager die folgenden Schritte aus, um den statischen IIS-Dateihandler auf Server- oder Website-Ebene zu entfernen:
- Navigieren Sie zum Feature Module.
- Wählen Sie StaticFileModule aus der Liste aus.
- Klicken Sie in der Randleiste Aktionen auf Entfernen.
Warnung
Wenn der statische IIS-Dateihandler aktiviert ist und das ASP.NET Core-Modul falsch konfiguriert wurde, werden statische Dateien bereitgestellt. Dies geschieht beispielsweise, wenn die Datei web.config nicht bereitgestellt worden ist.
- Platzieren Sie Codedateien einschließlich
.cs
und.cshtml
außerhalb des Webstammverzeichnisses des App-Projekts. Aus diesem Grund wird eine logische Trennung zwischen den clientseitigen Inhalten der App und dem serverbasierten Code erschaffen. Dadurch wird verhindert, dass serverseitiger Code aufgedeckt wird.
Bedienen Sie Dateien außerhalb von wwwroot, indem Sie IWebHostEnvironment.WebRootPath aktualisieren
Wenn IWebHostEnvironment.WebRootPath auf einen anderen Ordner als wwwroot
festgelegt ist:
- In der Entwicklungsumgebung werden statische Ressourcen, die sich sowohl unter
wwwroot
als auch dem aktualisiertenIWebHostEnvironment.WebRootPath
befinden, vonwwwroot
bedient. - In jeder anderen Umgebung als der Entwicklungsumgebung werden doppelt vorhandene statische Ressourcen aus dem aktualisierten
IWebHostEnvironment.WebRootPath
-Ordner bereitgestellt.
Betrachten Sie eine Web-App, die mit der leeren Webvorlage erstellt wurde:
Sie enthält eine Datei
Index.html
inwwwroot
undwwwroot-custom
.Mit der folgenden aktualisierten
Program.cs
-Datei, dieWebRootPath = "wwwroot-custom"
festlegt: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();
Im vorhergehenden Code bewirken Anforderungen an /
Folgendes:
- In der Entwicklungsumgebung wird
wwwroot/Index.html
zurückgegeben - In jeder anderen Umgebung als der Entwicklungsumgebung wird
wwwroot-custom/Index.html
zurückgegeben
Verwenden Sie eine der folgenden Ansätze, um sicherzustellen, dass Ressourcen aus wwwroot-custom
zurückgegeben werden:
Löschen Sie doppelte benannte Ressourcen in
wwwroot
.Legen Sie
"ASPNETCORE_ENVIRONMENT"
inProperties/launchSettings.json
auf einen beliebigen anderen Wert als"Development"
fest.Deaktivieren Sie statische Webressourcen vollständig, indem Sie
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
in der Projektdatei festlegen. WARNUNG: Durch das Deaktivieren statischer Webressourcen werden die Razor-Klassenbibliotheken deaktiviert.Fügen Sie der Projektdatei den folgenden JSON-Code hinzu:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
Der folgende Code aktualisiert IWebHostEnvironment.WebRootPath
auf einen nicht auf die Entwicklung bezogenen Wert, der garantiert, dass doppelte Inhalte aus wwwroot-custom
anstelle von wwwroot
zurückgegeben werden:
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();
Zusätzliche Ressourcen
Von Rick Anderson und Kirk Larkin
Bei statischen Dateien wie HTML, CSS, Images und JavaScript handelt es sich um Objekte, die Clients von einer ASP.NET Core-App standardmäßig direkt bereitgestellt werden.
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Bereitstellen statischer Dateien
Statische Dateien werden im Webstammverzeichnis des Projekts gespeichert. Das Standardverzeichnis lautet {content root}/wwwroot
, kann jedoch mit der Methode UseWebRoot geändert werden. Weitere Informationen finden Sie unter Inhaltsstammverzeichnis und Webstammverzeichnis.
Die Methode CreateDefaultBuilder legt das Inhaltsstammverzeichnis auf das aktuelle Verzeichnis fest:
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>();
});
}
Der vorangehende Code wurde mit der Web-App-Vorlage erstellt.
Auf statische Dateien kann über einen Pfad relativ zum Webstammverzeichnis zugegriffen werden. Die Webanwendung-Projektvorlagen verfügen beispielsweise über mehrere Ordner innerhalb des Ordners wwwroot
:
wwwroot
css
js
lib
Erstellen Sie ggf. den wwwroot/images-Ordner, und fügen Sie die Datei wwwroot/images/MyImage.jpg
hinzu. Das URI-Format für den Zugriff auf eine Datei im images
-Ordner ist https://<hostname>/images/<image_file_name>
. Beispiel: https://localhost:5001/images/MyImage.jpg
Verarbeiten von Dateien im Webstammverzeichnis
Mit den Standard-Webappvorlagen wird die UseStaticFiles-Methode in Startup.Configure
aufgerufen, die die Verarbeitung statischer Dateien ermöglicht:
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();
});
}
Die parameterlose Überladung der Methode UseStaticFiles
markiert die Dateien im Webstammverzeichnis als bereitstellbar. Folgendes Markup verweist auf wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Im vorhergehenden Code verweist die Tilde (~/
) auf das Webstammverzeichnis.
Bereitstellen von Dateien außerhalb des Webstammverzeichnisses
Erwägen Sie eine Verzeichnishierarchie, bei der sich die bereitzustellenden statischen Dateien außerhalb des Webstammverzeichnisses befinden:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Über eine Anforderung kann auf die Datei red-rose.jpg
zugegriffen werden, indem die Middleware für statische Dateien wie folgt konfiguriert wird:
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();
});
}
Im vorangehenden Code wird die MyStaticFiles-Verzeichnishierarchie öffentlich über das URI-Segment StaticFiles verfügbar gemacht. Eine Anforderung an https://<hostname>/StaticFiles/images/red-rose.jpg
dient der red-rose.jpg
-Datei.
Folgendes Markup verweist auf MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Festlegen von HTTP-Antwortheadern
Mit einem StaticFileOptions-Objekt können HTTP-Antwortheader festgelegt werden. Neben der Konfiguration statischer, über das Webstammverzeichnis bereitgestellter Dateien wird mit dem folgenden Code der Header Cache-Control
festgelegt:
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();
});
}
Der vorangehende Code legt „max-age“ auf 604800 Sekunden (7 Tage) fest.
Autorisierung statischer Dateien
Die ASP.NET Core-Vorlagen rufen UseStaticFiles vor UseAuthorization auf. Die meisten Apps folgen diesem Muster. Wenn die Middleware für statische Dateien vor der Autorisierungsmiddleware aufgerufen wird, gilt Folgendes:
- In den statischen Dateien werden keine Autorisierungsüberprüfungen durchgeführt.
- Statische Dateien, die von der Middleware für statische Dateien bereitgestellt werden – wie beispielsweise diejenigen unter
wwwroot
– sind öffentlich zugänglich.
So stellen Sie statische Dateien basierend auf Autorisierung bereit:
- Speichern Sie sie außerhalb von
wwwroot
. - Rufen Sie
UseStaticFiles
nach dem Aufruf vonUseAuthorization
auf, und geben Sie einen Pfad an. - Legen Sie die Autorisierungsrichtlinie für Fallbacks fest.
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.
Im vorstehenden Code erfordert die Richtlinie für die Fallbackautorisierung, dass alle Benutzer authentifiziert werden müssen. Endpunkte wie Controller, Razor Pages usw., die eigene Autorisierungsanforderungen angeben, verwenden die Autorisierungsrichtlinie für Fallbacks nicht. Beispielsweise verwenden Razor Pages, Controller oder Aktionsmethoden mit [AllowAnonymous]
oder [Authorize(PolicyName="MyPolicy")]
das angewendete Autorisierungsattribut anstelle der Autorisierungsrichtlinie für Fallbacks.
RequireAuthenticatedUser fügt der aktuellen Instanz DenyAnonymousAuthorizationRequirement hinzu. Dadurch wird die Authentifizierung des aktuellen Benutzers erzwungen.
Statische Ressourcen unter wwwroot
sind öffentlich zugänglich, weil die Middleware für statische Dateien (app.UseStaticFiles();
) vor UseAuthentication
aufgerufen wird. Statische Ressourcen im MyStaticFiles-Ordner erfordern eine Authentifizierung. Dies wird im Beispielcode veranschaulicht.
Eine Alternative zum Bereitstellen von Dateien basierend auf Autorisierung ist folgendes Verfahren:
- Speichern Sie sie außerhalb von
wwwroot
sowie außerhalb sämtlicher Verzeichnisse, auf die die Middleware für statische Dateien zugreifen kann. - Stellen Sie sie über eine Aktionsmethode bereit, für die die Autorisierung gilt, und geben Sie ein FileResult-Objekt zurück:
[Authorize]
public IActionResult BannerImage()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
Verzeichnissuche
Die Verzeichnissuche ermöglicht die Verzeichnisauflistung in angegebenen Verzeichnissen.
Die Verzeichnissuche ist aus Sicherheitsgründen standardmäßig deaktiviert. Weitere Informationen finden Sie unter Sicherheitsüberlegungen für statische Dateien.
Aktivieren Sie die Verzeichnissuche mit:
- 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();
});
}
Der vorangehende Code ermöglicht die Verzeichnissuche im Ordner wwwroot/images über die URL https://<hostname>/MyImages
mit Links zu den einzelnen Dateien und Ordnern:
Bereitstellen von Standarddokumenten
Durch das Festlegen einer Standardseite wird Besuchern ein Ausgangspunkt auf einer Website bereitgestellt. Rufen Sie die UseDefaultFiles-Methode auf, um eine Standarddatei aus wwwroot
zu stellen, ohne dass die Anforderungs-URL im Dateinamen enthalten sein muss:
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
muss vor UseStaticFiles
aufgerufen werden, damit die Standarddatei bereitgestellt wird. UseDefaultFiles
ist ein URL-Rewriter, der die Datei nicht verarbeiten kann.
Bei UseDefaultFiles
werden bei Anforderungen an einen Ordner in wwwroot
folgende Dateien durchsucht:
default.htm
default.html
index.htm
index.html
Die erste in der Liste gefundene Datei wird bereitgestellt, als wäre die Anforderung im Dateinamen enthalten. Die Browser-URL spiegelt weiterhin den angeforderten URI wider.
Mit dem folgenden Code wird der Standarddateiname in mydefault.html
geändert:
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
Der folgende Code zeigt Startup.Configure
mit dem vorherigen Code:
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 für Standarddokumente
In UseFileServer werden die Funktionen von UseStaticFiles
, UseDefaultFiles
und (optional) UseDirectoryBrowser
miteinander kombiniert.
Rufen Sie app.UseFileServer
auf, um die Bereitstellung statischer Dateien und der Standarddatei zu aktivieren. Die Verzeichnissuche ist nicht aktiviert. Der folgende Code zeigt Startup.Configure
mit UseFileServer
an:
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();
});
}
Mit dem folgenden Code wird die Bereitstellung statischer Dateien, der Standarddatei und der Verzeichnissuche aktiviert:
app.UseFileServer(enableDirectoryBrowsing: true);
Der folgende Code zeigt Startup.Configure
mit dem vorherigen Code:
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();
});
}
Betrachten Sie die folgende Verzeichnishierarchie:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
Mit dem folgenden Code wird die Bereitstellung statischer Dateien, der Standarddatei und der Verzeichnissuche von MyStaticFiles
aktiviert:
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 muss aufgerufen werden, wenn der EnableDirectoryBrowsing
-Eigenschaftswert true
lautet.
Unter Verwendung der Dateihierarchie und des vorangehenden Codes werden URLs wie folgt aufgelöst:
URI | Antwort |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Wenn im Verzeichnis MyStaticFiles keine Datei mit Standardnamen vorhanden ist, gibt https://<hostname>/StaticFiles
die Verzeichnisliste mit klickbaren Links zurück:
UseDefaultFiles und UseDirectoryBrowser führen eine clientseitige Umleitung vom Ziel-URI ohne nachgestellten /
zum Ziel-URI mit nachgestelltem /
durch. Beispielsweise von https://<hostname>/StaticFiles
zu https://<hostname>/StaticFiles/
. Relative URLs im Verzeichnis StaticFiles gelten ohne nachstehenden Schrägstrich (/
) als ungültig.
FileExtensionContentTypeProvider
Die Klasse FileExtensionContentTypeProvider enthält eine Mappings
-Eigenschaft, die als Zuordnung von Dateierweiterungen zu MIME-Inhaltstypen dient. Im folgenden Beispiel werden mehrere Dateierweiterungen bekannten MIME-Typen zugeordnet. Die Erweiterung .rtf wird ersetzt, und .mp4 wird entfernt:
// 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"
});
Der folgende Code zeigt Startup.Configure
mit dem vorherigen Code:
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();
});
}
Weitere Informationen finden Sie unter MIME-Inhaltstypen.
Inhaltstypen, die vom Standard abweichen
Die Middleware für statische Dateien erkennt fast 400 bekannte Dateiinhaltstypen. Wenn ein Benutzer eine Datei mit einem unbekannten Dateityp anfordert, übergibt die Middleware für statische Dateien die Anforderung an die nächste Middleware in der Pipeline. Wenn keine Middleware die Anforderung verarbeitet, wird die Meldung 404 Nicht gefunden zurückgegeben. Wenn die Verzeichnissuche aktiviert ist, wird ein Link zur Datei in einer Verzeichnisliste angezeigt.
Mit dem folgenden Code wird die Bereitstellung unbekannter Typen aktiviert und die unbekannte Datei als Image gerendert:
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
Der folgende Code zeigt Startup.Configure
mit dem vorherigen Code:
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();
});
}
Mit dem vorangehenden Code wird eine Anforderung für eine Datei mit unbekanntem Inhaltstyp als Image zurückgegeben.
Warnung
Die Aktivierung von ServeUnknownFileTypes stellt ein Sicherheitsrisiko dar. Diese Eigenschaft ist standardmäßig deaktiviert, von einer Verwendung wird abgeraten. FileExtensionContentTypeProvider bietet eine sicherere Alternative für die Bereitstellung von Dateien mit vom Standard abweichenden Erweiterungen.
Bereitstellen von Dateien aus mehreren Speicherorten
Bei UseStaticFiles
und UseFileServer
zeigt der Dateianbieter standardmäßig auf wwwroot
. Weitere Instanzen von UseStaticFiles
und UseFileServer
können mit anderen Dateianbietern bereitgestellt werden, um Dateien von anderen Speicherorten bereitzustellen. Weitere Informationen finden Sie in diesem GitHub-Issue.
Sicherheitsüberlegungen für statische Dateien
Warnung
UseDirectoryBrowser
und UseStaticFiles
können Geheimnisse aufdecken. Eine Deaktivierung der Verzeichnissuche in der Produktionsumgebung wird dringend empfohlen. Überprüfen Sie sorgfältig, welche Verzeichnisse über UseStaticFiles
oder UseDirectoryBrowser
aktiviert wurden. Das gesamte Verzeichnis und die zugehörigen Unterverzeichnisse werden öffentlich zugänglich gemacht. Speichern Sie Dateien, die für eine Bereitstellung in der Öffentlichkeit geeignet sind, in einem dafür vorgesehenen Verzeichnis wie z.B. <content_root>/wwwroot
. Trennen Sie diese Dateien von MVC-Ansichten, Razor Pages, Konfigurationsdateien usw.
Die URLs für Inhalte, die mit
UseDirectoryBrowser
undUseStaticFiles
verfügbar gemacht wurden, unterliegen der Groß-/Kleinschreibung und den Zeichenbeschränkungen des zugrunde liegenden Dateisystems. Bei Windows wird die Groß-/Kleinschreibung beispielsweise nicht beachtet, jedoch bei macOS und Linux.In IIS gehostete ASP.NET Core-Apps leiten über das ASP.NET Core-Modul alle Anforderungen an die App weiter, darunter die Anforderungen von statischen Dateien. Der IIS-Handler für statische Dateien wird nicht verwendet und hat keine Möglichkeit, Anforderungen zu verarbeiten.
Führen Sie im IIS-Manager die folgenden Schritte aus, um den statischen IIS-Dateihandler auf Server- oder Website-Ebene zu entfernen:
- Navigieren Sie zum Feature Module.
- Wählen Sie StaticFileModule aus der Liste aus.
- Klicken Sie in der Randleiste Aktionen auf Entfernen.
Warnung
Wenn der statische IIS-Dateihandler aktiviert ist und das ASP.NET Core-Modul falsch konfiguriert wurde, werden statische Dateien bereitgestellt. Dies geschieht beispielsweise, wenn die Datei web.config nicht bereitgestellt worden ist.
- Platzieren Sie Codedateien einschließlich
.cs
und.cshtml
außerhalb des Webstammverzeichnisses des App-Projekts. Aus diesem Grund wird eine logische Trennung zwischen den clientseitigen Inhalten der App und dem serverbasierten Code erschaffen. Dadurch wird verhindert, dass serverseitiger Code aufgedeckt wird.