Pliki statyczne w ASP.NET Core
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
Ostrzeżenie
Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz .NET i .NET Core Support Policy (Zasady obsługi platformy .NET Core). Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.
Ważne
Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
Autor: Rick Anderson
Pliki statyczne, takie jak HTML, CSS, images i JavaScript, to zasoby, które ASP.NET Aplikacja Core domyślnie obsługuje bezpośrednio klientom.
Aby uzyskać Blazor wskazówki dotyczące plików statycznych, które dodają lub zastępują wskazówki zawarte w tym artykule, zobacz ASP.NET Core Blazor plików statycznych.
Obsługa plików statycznych
Pliki statyczne są przechowywane w katalogu głównym projektu. Domyślny katalog to {content root}/wwwroot
, ale można go zmienić za pomocą UseWebRoot metody . Aby uzyskać więcej informacji, zobacz Katalog główny zawartości i Katalog główny sieci Web.
Metoda CreateBuilder ustawia katalog główny zawartości na bieżący katalog:
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();
Pliki statyczne są dostępne za pośrednictwem ścieżki względem katalogu głównego sieci Web. Na przykład szablony projektów aplikacji internetowej zawierają kilka folderów w folderze wwwroot
:
wwwroot
css
js
lib
Rozważ aplikację z plikiem wwwroot/images/MyImage.jpg
. Format identyfikatora URI umożliwiający dostęp do pliku w folderze images
to https://<hostname>/images/<image_file_name>
. Na przykład https://localhost:5001/images/MyImage.jpg
MapStaticAssets
Tworzenie wydajnych aplikacji internetowych wymaga optymalizacji dostarczania zasobów do przeglądarki. Możliwe optymalizacje obejmują:
- Obsłuż dany zasób raz, dopóki plik nie ulegnie zmianie lub przeglądarka wyczyści jego pamięć podręczną. Ustaw nagłówek ETag.
- Uniemożliwiaj przeglądarce używanie starych lub nieaktualnych zasobów po zaktualizowaniu aplikacji. Ustaw nagłówek Ostatnia modyfikacja.
- Skonfiguruj odpowiednie nagłówki buforowania.
- Użyj oprogramowania pośredniczącego buforowania.
- Jeśli to możliwe, obsłuż skompresowane wersje zasobów.
- Użyj sieci CDN , aby udostępnić zasoby bliżej użytkownika.
- Zminimalizuj rozmiar zasobów obsługiwanych w przeglądarce. Ta optymalizacja nie obejmuje minification.
MapStaticAssets to konwencje punktów końcowych routingu, które optymalizują dostarczanie zasobów statycznych w aplikacji. Jest ona przeznaczona do pracy ze wszystkimi strukturami interfejsu użytkownika, w tym Blazorz elementami , Razor Pages i MVC.
UseStaticFiles
Obsługuje również pliki statyczne, ale nie zapewnia tego samego poziomu optymalizacji co MapStaticAssets
. Aby zapoznać się z porównaniem elementów UseStaticFiles
i MapStaticAssets
, zobacz Optymalizowanie statycznego dostarczania zasobów internetowych.
Obsługa plików w katalogu głównym sieci Web
Domyślne szablony aplikacji internetowej wywołają metodę MapStaticAssets w Program.cs
pliku , która umożliwia obsługę plików statycznych:
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();
Przeciążenie metody bez UseStaticFiles
parametrów oznacza pliki w katalogu głównym sieci Web jako możliwe. Następujące odwołania wwwroot/images/MyImage.jpg
do znaczników:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
W poprzednim znaczniku znak ~
tyldy wskazuje katalog główny sieci Web.
Obsługa plików spoza katalogu głównego sieci Web
Rozważ hierarchię katalogów, w której pliki statyczne, które mają być obsługiwane, znajdują się poza katalogiem głównym sieci Web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Żądanie może uzyskać dostęp do red-rose.jpg
pliku, konfigurując oprogramowanie pośredniczące pliku statycznego w następujący sposób:
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();
W poprzednim kodzie hierarchia katalogów MyStaticFiles jest uwidoczniona publicznie za pośrednictwem segmentu identyfikatora URI StaticFiles . Żądanie https://<hostname>/StaticFiles/images/red-rose.jpg
obsługi red-rose.jpg
pliku.
Następujące odwołania MyStaticFiles/images/red-rose.jpg
do znaczników:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Aby obsłużyć pliki z wielu lokalizacji, zobacz Obsługa plików z wielu lokalizacji.
Ustawianie nagłówków odpowiedzi HTTP
Obiekt StaticFileOptions może służyć do ustawiania nagłówków odpowiedzi HTTP. Oprócz konfigurowania plików statycznych obsługujących z katalogu głównego sieci Web następujący kod ustawia nagłówek Cache-Control :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
}
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Powyższy kod udostępnia pliki statyczne publicznie w lokalnej pamięci podręcznej przez tydzień.
Autoryzacja pliku statycznego
Szablony ASP.NET Core są wywoływane MapStaticAssets przed wywołaniem metody UseAuthorization. Większość aplikacji jest zgodnie z tym wzorcem. Po wywołaniu oprogramowania pośredniczącego plików statycznych przed oprogramowaniem pośredniczącym autoryzacji:
- W plikach statycznych nie są wykonywane kontrole autoryzacji.
- Pliki statyczne obsługiwane przez oprogramowanie pośredniczące plików statycznych, takie jak w obszarze
wwwroot
, są publicznie dostępne.
Aby obsługiwać pliki statyczne na podstawie autoryzacji:
- Przechowuj je poza elementem
wwwroot
. - Wywołaj metodę
UseStaticFiles
, określając ścieżkę po wywołaniu metodyUseAuthorization
. - Ustaw zasady autoryzacji rezerwowej.
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();
W poprzednim kodzie zasady autoryzacji rezerwowej wymagają uwierzytelnienia wszystkich użytkowników. Punkty końcowe, takie jak kontrolery, Razor strony itp., które określają własne wymagania dotyczące autoryzacji, nie korzystają z zasad autoryzacji rezerwowej. Na przykład Razor strony, kontrolery lub metody akcji z zastosowanym atrybutem [AllowAnonymous]
autoryzacji lub [Authorize(PolicyName="MyPolicy")]
użyj ich, a nie zasad autoryzacji rezerwowej.
RequireAuthenticatedUser dodaje DenyAnonymousAuthorizationRequirement do bieżącego wystąpienia, co wymusza uwierzytelnienie bieżącego użytkownika.
Zasoby statyczne w obszarze wwwroot
są publicznie dostępne, ponieważ domyślne oprogramowanie pośredniczące plików statycznych (app.UseStaticFiles();
) jest wywoływane przed UseAuthentication
. Zasoby statyczne w folderze MyStaticFiles wymagają uwierzytelniania. Przykładowy kod pokazuje to.
Alternatywną metodą udostępniania plików na podstawie autoryzacji jest:
Przechowuj je poza katalogami
wwwroot
i dostępnymi dla oprogramowania pośredniczącego plików statycznych.Za pomocą metody akcji, do której jest stosowana autoryzacja FileResult i zwraca obiekt:
[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"); } }
Powyższe podejście wymaga strony lub punktu końcowego dla każdego pliku. Poniższy kod zwraca pliki lub przekazuje pliki dla uwierzytelnionych użytkowników:
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();
Plik IFormFile w poprzednim przykładzie używa buforu pamięci do przekazywania. Do obsługi przesyłania strumieniowego dużych plików. Zobacz Przekazywanie dużych plików za pomocą przesyłania strumieniowego.
Aby uzyskać pełny przykład, zobacz folder GitHub StaticFileAuth.
Przeglądanie katalogów
Przeglądanie katalogów umożliwia wyświetlanie listy katalogów w określonych katalogach.
Przeglądanie katalogów jest domyślnie wyłączone ze względów bezpieczeństwa. Aby uzyskać więcej informacji, zobacz Zagadnienia dotyczące zabezpieczeń plików statycznych.
Włącz przeglądanie katalogów za pomocą polecenia AddDirectoryBrowser i 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();
Powyższy kod umożliwia przeglądanie katalogów folderu wwwroot/images przy użyciu adresu URL https://<hostname>/MyImages
, z linkami do każdego pliku i folderu:
AddDirectoryBrowser
dodaje usługi wymagane przez oprogramowanie pośredniczące przeglądania katalogów, w tym HtmlEncoder. Te usługi mogą być dodawane przez inne wywołania, takie jak AddRazorPages, ale zalecamy wywołanie, AddDirectoryBrowser
aby upewnić się, że usługi są dodawane we wszystkich aplikacjach.
Obsługa dokumentów domyślnych
Ustawienie strony domyślnej zapewnia odwiedzającym punkt początkowy w witrynie. Aby obsłużyć plik domyślny bez wwwroot
konieczności uwzględnienia nazwy pliku przez adres URL żądania, wywołaj metodę UseDefaultFiles :
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
musi być wywoływana przed UseStaticFiles
udostępnieniem pliku domyślnego. UseDefaultFiles
jest autorem adresu URL, który nie obsługuje pliku.
Za pomocą polecenia UseDefaultFiles
żądania do folderu w wwwroot
wyszukiwaniu:
default.htm
default.html
index.htm
index.html
Pierwszy plik znaleziony na liście jest obsługiwany tak, jakby żądanie zawierało nazwę pliku. Adres URL przeglądarki nadal odzwierciedla żądany identyfikator URI. Na przykład w przykładowej aplikacji żądanie https://localhost:<port>/def/
obsługi default.html
z usługi wwwroot/def
.
Poniższy kod zmienia domyślną nazwę pliku na mydefault.html
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
UseFileServer dla dokumentów domyślnych
UseFileServer łączy funkcje UseStaticFiles
, UseDefaultFiles
i opcjonalnie UseDirectoryBrowser
.
Wywołaj metodę app.UseFileServer
w celu włączenia obsługi plików statycznych i pliku domyślnego. Przeglądanie katalogów nie jest włączone:
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();
Poniższy kod umożliwia obsługę plików statycznych, pliku domyślnego i przeglądania katalogów:
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();
Rozważ następującą hierarchię katalogów:
wwwroot
css
images
js
MyStaticFiles
defaultFiles
default.html
image3.png
images
MyImage.jpg
Poniższy kod umożliwia obsługę plików statycznych, pliku domyślnego i przeglądania katalogów:MyStaticFiles
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
AddDirectoryBrowser element musi być wywoływany, EnableDirectoryBrowsing
gdy wartość właściwości to true
.
Korzystając z poprzedniej hierarchii plików i kodu, adresy URL są rozpoznawane w następujący sposób:
Identyfikator URI | Response |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
lista katalogów |
https://<hostname>/StaticFiles/defaultFiles |
MyStaticFiles/defaultFiles/default.html |
https://<hostname>/StaticFiles/defaultFiles/image3.png |
MyStaticFiles/defaultFiles//image3.png |
Jeśli w katalogu MyStaticFiles nie istnieje żaden plik o nazwie domyślnej, https://<hostname>/StaticFiles
zwraca listę katalogów z linkami, które można kliknąć:
UseDefaultFiles i UseDirectoryBrowser wykonaj przekierowanie po stronie klienta z docelowego identyfikatora URI bez /
końcowego identyfikatora URI z końcowym /
identyfikatorem URI. Na przykład od https://<hostname>/StaticFiles
do https://<hostname>/StaticFiles/
. Względne adresy URL w katalogu StaticFiles są nieprawidłowe bez końcowego ukośnika (/
), chyba że RedirectToAppendTrailingSlash jest używana opcja DefaultFilesOptions .
FileExtensionContentTypeProvider
Klasa FileExtensionContentTypeProvider zawiera właściwość Mapowania , która służy jako mapowanie rozszerzeń plików na typy zawartości MIME. W poniższym przykładzie kilka rozszerzeń plików jest mapowanych na znane typy MIME. Rozszerzenie .rtf jest zastępowane i .mp4 jest usuwane:
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();
Zobacz Typy zawartości MIME.
Niestandardowe typy zawartości
Oprogramowanie pośredniczące plików statycznych rozumie prawie 400 znanych typów zawartości plików. Jeśli użytkownik żąda pliku z nieznanym typem pliku, oprogramowanie static file middleware przekazuje żądanie do następnego oprogramowania pośredniczącego w potoku. Jeśli żadne oprogramowanie pośredniczące nie obsługuje żądania, zostanie zwrócona odpowiedź 404 Nie znaleziono . Jeśli przeglądanie katalogów jest włączone, link do pliku jest wyświetlany na liście katalogów.
Poniższy kod umożliwia obsługę nieznanych typów i renderuje nieznany plik jako obraz:
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();
W poprzednim kodzie żądanie pliku o nieznanym typie zawartości jest zwracane jako obraz.
Ostrzeżenie
ServeUnknownFileTypes Włączenie jest zagrożeniem bezpieczeństwa. Jest on domyślnie wyłączony, a jego użycie jest odradzane. FileExtensionContentTypeProvider zapewnia bezpieczniejszą alternatywę dla obsługi plików z niestandardowymi rozszerzeniami.
Obsługa plików z wielu lokalizacji
Rozważmy następującą Razor stronę, na której jest wyświetlany /MyStaticFiles/image3.png
plik:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
i UseFileServer
domyślnie do dostawcy plików wskazującego wartość .wwwroot
Dodatkowe wystąpienia UseStaticFiles
programu i UseFileServer
mogą być udostępniane innym dostawcom plików w celu udostępniania plików z innych lokalizacji. Poniższy przykład wywołuje dwa razy, UseStaticFiles
aby obsługiwać pliki z obu wwwroot
elementów i MyStaticFiles
:
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Przy użyciu poprzedniego kodu:
- Zostanie
/MyStaticFiles/image3.png
wyświetlony plik. - Pomocnicy tagów obrazów AppendVersion nie są stosowane, ponieważ pomocnicy tagów zależą od WebRootFileProviderelementu .
WebRootFileProvider
nie został zaktualizowany w celu uwzględnieniaMyStaticFiles
folderu.
Poniższy kod aktualizuje element WebRootFileProvider
, który umożliwia pomocnikowi tagów obrazów podanie wersji:
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();
Uwaga
Powyższe podejście dotyczy Razor aplikacji Pages i MVC. Aby uzyskać wskazówki dotyczące Blazor Web Apps, zobacz ASP.NET Core Blazor plików statycznych.
Zagadnienia dotyczące zabezpieczeń plików statycznych
Ostrzeżenie
UseDirectoryBrowser
i UseStaticFiles
może wyciekać tajemnice. Wyłączenie przeglądania katalogów w środowisku produkcyjnym jest zdecydowanie zalecane. Dokładnie sprawdź, które katalogi są włączone za pośrednictwem programu UseStaticFiles
lub UseDirectoryBrowser
. Cały katalog i jego podkatalog stają się publicznie dostępne. Przechowuj pliki odpowiednie do obsługi publicznej w dedykowanym katalogu, takim jak <content_root>/wwwroot
. Oddziel te pliki od widoków MVC, Razor stron, plików konfiguracji itp.
Adresy URL zawartości udostępnianej za pomocą
UseDirectoryBrowser
UseStaticFiles
elementu , iMapStaticAssets
podlegają ograniczeniom poufności wielkości liter i znaków bazowego systemu plików. Na przykład system Windows nie uwzględnia wielkości liter, ale systemy macOS i Linux nie są.ASP.NET Core aplikacje hostowane w usługach IIS używają modułu podstawowego ASP.NET do przekazywania wszystkich żądań do aplikacji, w tym żądań plików statycznych. Program obsługi plików statycznych usług IIS nie jest używany i nie ma szans na obsługę żądań.
Wykonaj następujące kroki w Menedżerze usług IIS, aby usunąć program obsługi plików statycznych usług IIS na poziomie serwera lub witryny internetowej:
- Przejdź do funkcji Moduły .
- Wybierz pozycję StaticFileModule na liście.
- Kliknij przycisk Usuń na pasku bocznym Akcje .
Ostrzeżenie
Jeśli program obsługi plików statycznych usług IIS jest włączony , a moduł ASP.NET Core jest niepoprawnie skonfigurowany, obsługiwane są pliki statyczne. Dzieje się tak, na przykład jeśli plik web.config nie jest wdrożony.
- Umieść pliki kodu, w tym
.cs
i.cshtml
, poza katalogem głównym projektu aplikacji. Dlatego separacja logiczna jest tworzona między zawartością po stronie klienta aplikacji a kodem opartym na serwerze. Zapobiega to wyciekowi kodu po stronie serwera.
Obsługa plików poza witryną wwwroot przez zaktualizowanie elementu IWebHostEnvironment.WebRootPath
Gdy IWebHostEnvironment.WebRootPath jest ustawiona wartość folderu innego niż wwwroot
:
- W środowisku projektowym zasoby statyczne znajdujące się zarówno w programie , jak
wwwroot
i zaktualizowaneIWebHostEnvironment.WebRootPath
są obsługiwane z witrynywwwroot
. - W dowolnym środowisku innym niż programowanie zduplikowane zasoby statyczne są obsługiwane ze zaktualizowanego
IWebHostEnvironment.WebRootPath
folderu.
Rozważmy aplikację internetową utworzoną przy użyciu pustego szablonu internetowego:
Zawiera plik
Index.html
w plikachwwwroot
iwwwroot-custom
.Przy użyciu następującego zaktualizowanego
Program.cs
pliku, który ustawia wartośćWebRootPath = "wwwroot-custom"
:var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = args, // Look for static files in "wwwroot-custom" WebRootPath = "wwwroot-custom" }); var app = builder.Build(); app.UseDefaultFiles(); app.MapStaticAssets(); app.Run();
W poprzednim kodzie żądania do /
:
- W zwracaniu środowiska deweloperskiego
wwwroot/Index.html
- W dowolnym środowisku innym niż zwrot programowania
wwwroot-custom/Index.html
Aby upewnić się, że zasoby z wwwroot-custom
programu zostaną zwrócone, użyj jednego z następujących metod:
Usuń zduplikowane nazwane zasoby w pliku
wwwroot
.Ustaw
"ASPNETCORE_ENVIRONMENT"
wartość naProperties/launchSettings.json
dowolną wartość inną niż"Development"
.Całkowicie wyłącz statyczne zasoby internetowe przez ustawienie
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
w pliku projektu. OSTRZEŻENIE, wyłączenie statycznych zasobów internetowych powoduje wyłączenie Razor bibliotek klas.Dodaj następujący kod XML do pliku projektu:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
Poniższy kod aktualizuje IWebHostEnvironment.WebRootPath
wartość niezwiązaną z programowaniem, co gwarantuje zwrócenie wwwroot-custom
zduplikowanej zawartości zamiast wwwroot
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Examine Hosting environment: logging value
EnvironmentName = Environments.Staging,
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
app.Environment.IsDevelopment().ToString());
app.UseDefaultFiles();
app.MapStaticAssets();
app.Run();
Dodatkowe zasoby
Autor: Rick Anderson
Pliki statyczne, takie jak HTML, CSS, images i JavaScript, to zasoby, które ASP.NET Aplikacja Core domyślnie obsługuje bezpośrednio klientom.
Obsługa plików statycznych
Pliki statyczne są przechowywane w katalogu głównym projektu. Domyślny katalog to {content root}/wwwroot
, ale można go zmienić za pomocą UseWebRoot metody . Aby uzyskać więcej informacji, zobacz Katalog główny zawartości i Katalog główny sieci Web.
Metoda CreateBuilder ustawia katalog główny zawartości na bieżący katalog:
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();
Pliki statyczne są dostępne za pośrednictwem ścieżki względem katalogu głównego sieci Web. Na przykład szablony projektów aplikacji internetowej zawierają kilka folderów w folderze wwwroot
:
wwwroot
css
js
lib
Rozważ utworzenie folderu wwwroot/images i dodanie wwwroot/images/MyImage.jpg
pliku. Format identyfikatora URI umożliwiający dostęp do pliku w folderze images
to https://<hostname>/images/<image_file_name>
. Na przykład https://localhost:5001/images/MyImage.jpg
Obsługa plików w katalogu głównym sieci Web
Domyślne szablony aplikacji internetowej wywołają metodę UseStaticFiles w Program.cs
pliku , która umożliwia obsługę plików statycznych:
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();
Przeciążenie metody bez UseStaticFiles
parametrów oznacza pliki w katalogu głównym sieci Web jako możliwe. Następujące odwołania wwwroot/images/MyImage.jpg
do znaczników:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
W poprzednim znaczniku znak ~
tyldy wskazuje katalog główny sieci Web.
Obsługa plików spoza katalogu głównego sieci Web
Rozważ hierarchię katalogów, w której pliki statyczne, które mają być obsługiwane, znajdują się poza katalogiem głównym sieci Web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Żądanie może uzyskać dostęp do red-rose.jpg
pliku, konfigurując oprogramowanie pośredniczące pliku statycznego w następujący sposób:
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();
W poprzednim kodzie hierarchia katalogów MyStaticFiles jest uwidoczniona publicznie za pośrednictwem segmentu identyfikatora URI StaticFiles . Żądanie https://<hostname>/StaticFiles/images/red-rose.jpg
obsługi red-rose.jpg
pliku.
Następujące odwołania MyStaticFiles/images/red-rose.jpg
do znaczników:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Aby obsłużyć pliki z wielu lokalizacji, zobacz Obsługa plików z wielu lokalizacji.
Ustawianie nagłówków odpowiedzi HTTP
Obiekt StaticFileOptions może służyć do ustawiania nagłówków odpowiedzi HTTP. Oprócz konfigurowania plików statycznych obsługujących z katalogu głównego sieci Web następujący kod ustawia nagłówek Cache-Control :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
}
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Powyższy kod udostępnia pliki statyczne publicznie w lokalnej pamięci podręcznej przez tydzień (604800 sekund).
Autoryzacja pliku statycznego
Szablony ASP.NET Core są wywoływane UseStaticFiles przed wywołaniem metody UseAuthorization. Większość aplikacji jest zgodnie z tym wzorcem. Po wywołaniu oprogramowania pośredniczącego plików statycznych przed oprogramowaniem pośredniczącym autoryzacji:
- W plikach statycznych nie są wykonywane kontrole autoryzacji.
- Pliki statyczne obsługiwane przez oprogramowanie pośredniczące plików statycznych, takie jak w obszarze
wwwroot
, są publicznie dostępne.
Aby obsługiwać pliki statyczne na podstawie autoryzacji:
- Przechowuj je poza elementem
wwwroot
. - Wywołaj metodę
UseStaticFiles
, określając ścieżkę po wywołaniu metodyUseAuthorization
. - Ustaw zasady autoryzacji rezerwowej.
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();
W poprzednim kodzie zasady autoryzacji rezerwowej wymagają uwierzytelnienia wszystkich użytkowników. Punkty końcowe, takie jak kontrolery, Razor strony itp., które określają własne wymagania dotyczące autoryzacji, nie korzystają z zasad autoryzacji rezerwowej. Na przykład Razor strony, kontrolery lub metody akcji z zastosowanym atrybutem [AllowAnonymous]
autoryzacji lub [Authorize(PolicyName="MyPolicy")]
użyj ich, a nie zasad autoryzacji rezerwowej.
RequireAuthenticatedUser dodaje DenyAnonymousAuthorizationRequirement do bieżącego wystąpienia, co wymusza uwierzytelnienie bieżącego użytkownika.
Zasoby statyczne w obszarze wwwroot
są publicznie dostępne, ponieważ domyślne oprogramowanie pośredniczące plików statycznych (app.UseStaticFiles();
) jest wywoływane przed UseAuthentication
. Zasoby statyczne w folderze MyStaticFiles wymagają uwierzytelniania. Przykładowy kod pokazuje to.
Alternatywną metodą udostępniania plików na podstawie autoryzacji jest:
Przechowuj je poza katalogami
wwwroot
i dostępnymi dla oprogramowania pośredniczącego plików statycznych.Za pomocą metody akcji, do której jest stosowana autoryzacja FileResult i zwraca obiekt:
[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"); } }
Powyższe podejście wymaga strony lub punktu końcowego dla każdego pliku. Poniższy kod zwraca pliki lub przekazuje pliki dla uwierzytelnionych użytkowników:
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();
Aby uzyskać pełny przykład, zobacz folder GitHub StaticFileAuth.
Przeglądanie katalogów
Przeglądanie katalogów umożliwia wyświetlanie listy katalogów w określonych katalogach.
Przeglądanie katalogów jest domyślnie wyłączone ze względów bezpieczeństwa. Aby uzyskać więcej informacji, zobacz Zagadnienia dotyczące zabezpieczeń plików statycznych.
Włącz przeglądanie katalogów za pomocą polecenia AddDirectoryBrowser i 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();
Powyższy kod umożliwia przeglądanie katalogów folderu wwwroot/images przy użyciu adresu URL https://<hostname>/MyImages
, z linkami do każdego pliku i folderu:
AddDirectoryBrowser
dodaje usługi wymagane przez oprogramowanie pośredniczące przeglądania katalogów, w tym HtmlEncoder. Te usługi mogą być dodawane przez inne wywołania, takie jak AddRazorPages, ale zalecamy wywołanie, AddDirectoryBrowser
aby upewnić się, że usługi są dodawane we wszystkich aplikacjach.
Obsługa dokumentów domyślnych
Ustawienie strony domyślnej zapewnia odwiedzającym punkt początkowy w witrynie. Aby obsłużyć plik domyślny bez wwwroot
konieczności uwzględnienia nazwy pliku przez adres URL żądania, wywołaj metodę UseDefaultFiles :
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
musi być wywoływana przed UseStaticFiles
udostępnieniem pliku domyślnego. UseDefaultFiles
jest autorem adresu URL, który nie obsługuje pliku.
Za pomocą polecenia UseDefaultFiles
żądania do folderu w wwwroot
wyszukiwaniu:
default.htm
default.html
index.htm
index.html
Pierwszy plik znaleziony na liście jest obsługiwany tak, jakby żądanie zawierało nazwę pliku. Adres URL przeglądarki nadal odzwierciedla żądany identyfikator URI.
Poniższy kod zmienia domyślną nazwę pliku na mydefault.html
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
UseFileServer dla dokumentów domyślnych
UseFileServer łączy funkcje UseStaticFiles
, UseDefaultFiles
i opcjonalnie UseDirectoryBrowser
.
Wywołaj metodę app.UseFileServer
w celu włączenia obsługi plików statycznych i pliku domyślnego. Przeglądanie katalogów nie jest włączone:
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();
Poniższy kod umożliwia obsługę plików statycznych, pliku domyślnego i przeglądania katalogów:
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();
Rozważ następującą hierarchię katalogów:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
Poniższy kod umożliwia obsługę plików statycznych, pliku domyślnego i przeglądania katalogów:MyStaticFiles
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
AddDirectoryBrowser element musi być wywoływany, EnableDirectoryBrowsing
gdy wartość właściwości to true
.
Korzystając z poprzedniej hierarchii plików i kodu, adresy URL są rozpoznawane w następujący sposób:
Identyfikator URI | Response |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Jeśli w katalogu MyStaticFiles nie istnieje żaden plik o nazwie domyślnej, https://<hostname>/StaticFiles
zwraca listę katalogów z linkami, które można kliknąć:
UseDefaultFiles i UseDirectoryBrowser wykonaj przekierowanie po stronie klienta z docelowego identyfikatora URI bez /
końcowego identyfikatora URI z końcowym /
identyfikatorem URI. Na przykład od https://<hostname>/StaticFiles
do https://<hostname>/StaticFiles/
. Względne adresy URL w katalogu StaticFiles są nieprawidłowe bez końcowego ukośnika (/
), chyba że RedirectToAppendTrailingSlash jest używana opcja DefaultFilesOptions .
FileExtensionContentTypeProvider
Klasa FileExtensionContentTypeProvider zawiera Mappings
właściwość, która służy jako mapowanie rozszerzeń plików na typy zawartości MIME. W poniższym przykładzie kilka rozszerzeń plików jest mapowanych na znane typy MIME. Rozszerzenie .rtf jest zastępowane i .mp4 jest usuwane:
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();
Zobacz Typy zawartości MIME.
Niestandardowe typy zawartości
Oprogramowanie pośredniczące plików statycznych rozumie prawie 400 znanych typów zawartości plików. Jeśli użytkownik żąda pliku z nieznanym typem pliku, oprogramowanie static file middleware przekazuje żądanie do następnego oprogramowania pośredniczącego w potoku. Jeśli żadne oprogramowanie pośredniczące nie obsługuje żądania, zostanie zwrócona odpowiedź 404 Nie znaleziono . Jeśli przeglądanie katalogów jest włączone, link do pliku jest wyświetlany na liście katalogów.
Poniższy kod umożliwia obsługę nieznanych typów i renderuje nieznany plik jako obraz:
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();
W poprzednim kodzie żądanie pliku o nieznanym typie zawartości jest zwracane jako obraz.
Ostrzeżenie
ServeUnknownFileTypes Włączenie jest zagrożeniem bezpieczeństwa. Jest on domyślnie wyłączony, a jego użycie jest odradzane. FileExtensionContentTypeProvider zapewnia bezpieczniejszą alternatywę dla obsługi plików z niestandardowymi rozszerzeniami.
Obsługa plików z wielu lokalizacji
Rozważmy następującą Razor stronę, na której jest wyświetlany /MyStaticFiles/image3.png
plik:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
i UseFileServer
domyślnie do dostawcy plików wskazującego wartość .wwwroot
Dodatkowe wystąpienia UseStaticFiles
programu i UseFileServer
mogą być udostępniane innym dostawcom plików w celu udostępniania plików z innych lokalizacji. Poniższy przykład wywołuje dwa razy, UseStaticFiles
aby obsługiwać pliki z obu wwwroot
elementów i MyStaticFiles
:
app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Przy użyciu poprzedniego kodu:
- Zostanie
/MyStaticFiles/image3.png
wyświetlony plik. - Pomocnicy tagów obrazów AppendVersion nie są stosowane, ponieważ pomocnicy tagów zależą od WebRootFileProviderelementu .
WebRootFileProvider
nie został zaktualizowany w celu uwzględnieniaMyStaticFiles
folderu.
Poniższy kod aktualizuje element WebRootFileProvider
, który umożliwia pomocnikowi tagów obrazów podanie wersji:
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();
Uwaga
Powyższe podejście dotyczy Razor aplikacji Pages i MVC. Aby uzyskać wskazówki dotyczące Blazor Web Apps, zobacz ASP.NET Core Blazor plików statycznych.
Zagadnienia dotyczące zabezpieczeń plików statycznych
Ostrzeżenie
UseDirectoryBrowser
i UseStaticFiles
może wyciekać tajemnice. Wyłączenie przeglądania katalogów w środowisku produkcyjnym jest zdecydowanie zalecane. Dokładnie sprawdź, które katalogi są włączone za pośrednictwem programu UseStaticFiles
lub UseDirectoryBrowser
. Cały katalog i jego podkatalog stają się publicznie dostępne. Przechowuj pliki odpowiednie do obsługi publicznej w dedykowanym katalogu, takim jak <content_root>/wwwroot
. Oddziel te pliki od widoków MVC, Razor stron, plików konfiguracji itp.
Adresy URL zawartości uwidocznionej
UseDirectoryBrowser
UseStaticFiles
i podlegają ograniczeniom poufności i znaków wielkości liter w podstawowym systemie plików. Na przykład system Windows nie uwzględnia wielkości liter, ale systemy macOS i Linux nie są.ASP.NET Core aplikacje hostowane w usługach IIS używają modułu podstawowego ASP.NET do przekazywania wszystkich żądań do aplikacji, w tym żądań plików statycznych. Program obsługi plików statycznych usług IIS nie jest używany i nie ma szans na obsługę żądań.
Wykonaj następujące kroki w Menedżerze usług IIS, aby usunąć program obsługi plików statycznych usług IIS na poziomie serwera lub witryny internetowej:
- Przejdź do funkcji Moduły .
- Wybierz pozycję StaticFileModule na liście.
- Kliknij przycisk Usuń na pasku bocznym Akcje .
Ostrzeżenie
Jeśli program obsługi plików statycznych usług IIS jest włączony , a moduł ASP.NET Core jest niepoprawnie skonfigurowany, obsługiwane są pliki statyczne. Dzieje się tak, na przykład jeśli plik web.config nie jest wdrożony.
- Umieść pliki kodu, w tym
.cs
i.cshtml
, poza katalogem głównym projektu aplikacji. Dlatego separacja logiczna jest tworzona między zawartością po stronie klienta aplikacji a kodem opartym na serwerze. Zapobiega to wyciekowi kodu po stronie serwera.
Obsługa plików poza witryną wwwroot przez zaktualizowanie elementu IWebHostEnvironment.WebRootPath
Gdy IWebHostEnvironment.WebRootPath jest ustawiona wartość folderu innego niż wwwroot
:
- W środowisku projektowym zasoby statyczne znajdujące się zarówno w programie , jak
wwwroot
i zaktualizowaneIWebHostEnvironment.WebRootPath
są obsługiwane z witrynywwwroot
. - W dowolnym środowisku innym niż programowanie zduplikowane zasoby statyczne są obsługiwane ze zaktualizowanego
IWebHostEnvironment.WebRootPath
folderu.
Rozważmy aplikację internetową utworzoną przy użyciu pustego szablonu internetowego:
Zawiera plik
Index.html
w plikachwwwroot
iwwwroot-custom
.Przy użyciu następującego zaktualizowanego
Program.cs
pliku, który ustawia wartośćWebRootPath = "wwwroot-custom"
:var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = args, // Look for static files in "wwwroot-custom" WebRootPath = "wwwroot-custom" }); var app = builder.Build(); app.UseDefaultFiles(); app.UseStaticFiles(); app.Run();
W poprzednim kodzie żądania do /
:
- W zwracaniu środowiska deweloperskiego
wwwroot/Index.html
- W dowolnym środowisku innym niż zwrot programowania
wwwroot-custom/Index.html
Aby upewnić się, że zasoby z wwwroot-custom
programu zostaną zwrócone, użyj jednego z następujących metod:
Usuń zduplikowane nazwane zasoby w pliku
wwwroot
.Ustaw
"ASPNETCORE_ENVIRONMENT"
wartość naProperties/launchSettings.json
dowolną wartość inną niż"Development"
.Całkowicie wyłącz statyczne zasoby internetowe przez ustawienie
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
w pliku projektu. OSTRZEŻENIE, wyłączenie statycznych zasobów internetowych powoduje wyłączenie Razor bibliotek klas.Dodaj następujący kod JSON do pliku projektu:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
Poniższy kod aktualizuje IWebHostEnvironment.WebRootPath
wartość niezwiązaną z programowaniem, co gwarantuje zwrócenie wwwroot-custom
zduplikowanej zawartości zamiast wwwroot
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Examine Hosting environment: logging value
EnvironmentName = Environments.Staging,
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
app.Environment.IsDevelopment().ToString());
app.UseDefaultFiles();
app.UseStaticFiles();
app.Run();
Dodatkowe zasoby
Autorzy: Rick Anderson i Kirk Larkin
Pliki statyczne, takie jak HTML, CSS, images i JavaScript, to zasoby, które ASP.NET Aplikacja Core domyślnie obsługuje bezpośrednio klientom.
Obsługa plików statycznych
Pliki statyczne są przechowywane w katalogu głównym projektu. Domyślny katalog to {content root}/wwwroot
, ale można go zmienić za pomocą UseWebRoot metody . Aby uzyskać więcej informacji, zobacz Katalog główny zawartości i Katalog główny sieci Web.
Metoda CreateBuilder ustawia katalog główny zawartości na bieżący katalog:
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();
Pliki statyczne są dostępne za pośrednictwem ścieżki względem katalogu głównego sieci Web. Na przykład szablony projektów aplikacji internetowej zawierają kilka folderów w folderze wwwroot
:
wwwroot
css
js
lib
Rozważ utworzenie folderu wwwroot/images i dodanie wwwroot/images/MyImage.jpg
pliku. Format identyfikatora URI umożliwiający dostęp do pliku w folderze images
to https://<hostname>/images/<image_file_name>
. Na przykład https://localhost:5001/images/MyImage.jpg
Obsługa plików w katalogu głównym sieci Web
Domyślne szablony aplikacji internetowej wywołają metodę UseStaticFiles w Program.cs
pliku , która umożliwia obsługę plików statycznych:
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();
Przeciążenie metody bez UseStaticFiles
parametrów oznacza pliki w katalogu głównym sieci Web jako możliwe. Następujące odwołania wwwroot/images/MyImage.jpg
do znaczników:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
W poprzednim znaczniku znak ~
tyldy wskazuje katalog główny sieci Web.
Obsługa plików spoza katalogu głównego sieci Web
Rozważ hierarchię katalogów, w której pliki statyczne, które mają być obsługiwane, znajdują się poza katalogiem głównym sieci Web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Żądanie może uzyskać dostęp do red-rose.jpg
pliku, konfigurując oprogramowanie pośredniczące pliku statycznego w następujący sposób:
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();
W poprzednim kodzie hierarchia katalogów MyStaticFiles jest uwidoczniona publicznie za pośrednictwem segmentu identyfikatora URI StaticFiles . Żądanie https://<hostname>/StaticFiles/images/red-rose.jpg
obsługi red-rose.jpg
pliku.
Następujące odwołania MyStaticFiles/images/red-rose.jpg
do znaczników:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Aby obsłużyć pliki z wielu lokalizacji, zobacz Obsługa plików z wielu lokalizacji.
Ustawianie nagłówków odpowiedzi HTTP
Obiekt StaticFileOptions może służyć do ustawiania nagłówków odpowiedzi HTTP. Oprócz konfigurowania plików statycznych obsługujących z katalogu głównego sieci Web następujący kod ustawia nagłówek Cache-Control :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
}
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Powyższy kod udostępnia pliki statyczne publicznie w lokalnej pamięci podręcznej przez tydzień (604800 sekund).
Autoryzacja pliku statycznego
Szablony ASP.NET Core są wywoływane UseStaticFiles przed wywołaniem metody UseAuthorization. Większość aplikacji jest zgodnie z tym wzorcem. Po wywołaniu oprogramowania pośredniczącego plików statycznych przed oprogramowaniem pośredniczącym autoryzacji:
- W plikach statycznych nie są wykonywane kontrole autoryzacji.
- Pliki statyczne obsługiwane przez oprogramowanie pośredniczące plików statycznych, takie jak w obszarze
wwwroot
, są publicznie dostępne.
Aby obsługiwać pliki statyczne na podstawie autoryzacji:
- Przechowuj je poza elementem
wwwroot
. - Wywołaj metodę
UseStaticFiles
, określając ścieżkę po wywołaniu metodyUseAuthorization
. - Ustaw zasady autoryzacji rezerwowej.
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();
W poprzednim kodzie zasady autoryzacji rezerwowej wymagają uwierzytelnienia wszystkich użytkowników. Punkty końcowe, takie jak kontrolery, Razor strony itp., które określają własne wymagania dotyczące autoryzacji, nie korzystają z zasad autoryzacji rezerwowej. Na przykład Razor strony, kontrolery lub metody akcji z zastosowanym atrybutem [AllowAnonymous]
autoryzacji lub [Authorize(PolicyName="MyPolicy")]
użyj ich, a nie zasad autoryzacji rezerwowej.
RequireAuthenticatedUser dodaje DenyAnonymousAuthorizationRequirement do bieżącego wystąpienia, co wymusza uwierzytelnienie bieżącego użytkownika.
Zasoby statyczne w obszarze wwwroot
są publicznie dostępne, ponieważ domyślne oprogramowanie pośredniczące plików statycznych (app.UseStaticFiles();
) jest wywoływane przed UseAuthentication
. Zasoby statyczne w folderze MyStaticFiles wymagają uwierzytelniania. Przykładowy kod pokazuje to.
Alternatywną metodą udostępniania plików na podstawie autoryzacji jest:
- Przechowuj je poza katalogami
wwwroot
i dostępnymi dla oprogramowania pośredniczącego plików statycznych. - Za pomocą metody akcji, do której jest stosowana autoryzacja FileResult i zwraca obiekt:
[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");
}
}
Przeglądanie katalogów
Przeglądanie katalogów umożliwia wyświetlanie listy katalogów w określonych katalogach.
Przeglądanie katalogów jest domyślnie wyłączone ze względów bezpieczeństwa. Aby uzyskać więcej informacji, zobacz Zagadnienia dotyczące zabezpieczeń plików statycznych.
Włącz przeglądanie katalogów za pomocą polecenia AddDirectoryBrowser i 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();
Powyższy kod umożliwia przeglądanie katalogów folderu wwwroot/images przy użyciu adresu URL https://<hostname>/MyImages
, z linkami do każdego pliku i folderu:
AddDirectoryBrowser
dodaje usługi wymagane przez oprogramowanie pośredniczące przeglądania katalogów, w tym HtmlEncoder. Te usługi mogą być dodawane przez inne wywołania, takie jak AddRazorPages, ale zalecamy wywołanie, AddDirectoryBrowser
aby upewnić się, że usługi są dodawane we wszystkich aplikacjach.
Obsługa dokumentów domyślnych
Ustawienie strony domyślnej zapewnia odwiedzającym punkt początkowy w witrynie. Aby obsłużyć plik domyślny bez wwwroot
konieczności uwzględnienia nazwy pliku przez adres URL żądania, wywołaj metodę UseDefaultFiles :
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
musi być wywoływana przed UseStaticFiles
udostępnieniem pliku domyślnego. UseDefaultFiles
jest autorem adresu URL, który nie obsługuje pliku.
Za pomocą polecenia UseDefaultFiles
żądania do folderu w wwwroot
wyszukiwaniu:
default.htm
default.html
index.htm
index.html
Pierwszy plik znaleziony na liście jest obsługiwany tak, jakby żądanie zawierało nazwę pliku. Adres URL przeglądarki nadal odzwierciedla żądany identyfikator URI.
Poniższy kod zmienia domyślną nazwę pliku na mydefault.html
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
UseFileServer dla dokumentów domyślnych
UseFileServer łączy funkcje UseStaticFiles
, UseDefaultFiles
i opcjonalnie UseDirectoryBrowser
.
Wywołaj metodę app.UseFileServer
w celu włączenia obsługi plików statycznych i pliku domyślnego. Przeglądanie katalogów nie jest włączone:
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();
Poniższy kod umożliwia obsługę plików statycznych, pliku domyślnego i przeglądania katalogów:
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();
Rozważ następującą hierarchię katalogów:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
Poniższy kod umożliwia obsługę plików statycznych, pliku domyślnego i przeglądania katalogów:MyStaticFiles
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
AddDirectoryBrowser element musi być wywoływany, EnableDirectoryBrowsing
gdy wartość właściwości to true
.
Korzystając z poprzedniej hierarchii plików i kodu, adresy URL są rozpoznawane w następujący sposób:
Identyfikator URI | Response |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Jeśli w katalogu MyStaticFiles nie istnieje żaden plik o nazwie domyślnej, https://<hostname>/StaticFiles
zwraca listę katalogów z linkami, które można kliknąć:
UseDefaultFiles i UseDirectoryBrowser wykonaj przekierowanie po stronie klienta z docelowego identyfikatora URI bez /
końcowego identyfikatora URI z końcowym /
identyfikatorem URI. Na przykład od https://<hostname>/StaticFiles
do https://<hostname>/StaticFiles/
. Względne adresy URL w katalogu StaticFiles są nieprawidłowe bez końcowego ukośnika (/
), chyba że RedirectToAppendTrailingSlash jest używana opcja DefaultFilesOptions .
FileExtensionContentTypeProvider
Klasa FileExtensionContentTypeProvider zawiera Mappings
właściwość, która służy jako mapowanie rozszerzeń plików na typy zawartości MIME. W poniższym przykładzie kilka rozszerzeń plików jest mapowanych na znane typy MIME. Rozszerzenie .rtf jest zastępowane i .mp4 jest usuwane:
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();
Zobacz Typy zawartości MIME.
Niestandardowe typy zawartości
Oprogramowanie pośredniczące plików statycznych rozumie prawie 400 znanych typów zawartości plików. Jeśli użytkownik żąda pliku z nieznanym typem pliku, oprogramowanie static file middleware przekazuje żądanie do następnego oprogramowania pośredniczącego w potoku. Jeśli żadne oprogramowanie pośredniczące nie obsługuje żądania, zostanie zwrócona odpowiedź 404 Nie znaleziono . Jeśli przeglądanie katalogów jest włączone, link do pliku jest wyświetlany na liście katalogów.
Poniższy kod umożliwia obsługę nieznanych typów i renderuje nieznany plik jako obraz:
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();
W poprzednim kodzie żądanie pliku o nieznanym typie zawartości jest zwracane jako obraz.
Ostrzeżenie
ServeUnknownFileTypes Włączenie jest zagrożeniem bezpieczeństwa. Jest on domyślnie wyłączony, a jego użycie jest odradzane. FileExtensionContentTypeProvider zapewnia bezpieczniejszą alternatywę dla obsługi plików z niestandardowymi rozszerzeniami.
Obsługa plików z wielu lokalizacji
Rozważmy następującą Razor stronę, na której jest wyświetlany /MyStaticFiles/image3.png
plik:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
i UseFileServer
domyślnie do dostawcy plików wskazującego wartość .wwwroot
Dodatkowe wystąpienia UseStaticFiles
programu i UseFileServer
mogą być udostępniane innym dostawcom plików w celu udostępniania plików z innych lokalizacji. Poniższy przykład wywołuje dwa razy, UseStaticFiles
aby obsługiwać pliki z obu wwwroot
elementów i MyStaticFiles
:
app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Przy użyciu poprzedniego kodu:
- Zostanie
/MyStaticFiles/image3.png
wyświetlony plik. - Pomocnicy tagów obrazów AppendVersion nie są stosowane, ponieważ pomocnicy tagów zależą od WebRootFileProviderelementu .
WebRootFileProvider
nie został zaktualizowany w celu uwzględnieniaMyStaticFiles
folderu.
Poniższy kod aktualizuje element WebRootFileProvider
, który umożliwia pomocnikowi tagów obrazów podanie wersji:
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();
Zagadnienia dotyczące zabezpieczeń plików statycznych
Ostrzeżenie
UseDirectoryBrowser
i UseStaticFiles
może wyciekać tajemnice. Wyłączenie przeglądania katalogów w środowisku produkcyjnym jest zdecydowanie zalecane. Dokładnie sprawdź, które katalogi są włączone za pośrednictwem programu UseStaticFiles
lub UseDirectoryBrowser
. Cały katalog i jego podkatalog stają się publicznie dostępne. Przechowuj pliki odpowiednie do obsługi publicznej w dedykowanym katalogu, takim jak <content_root>/wwwroot
. Oddziel te pliki od widoków MVC, Razor stron, plików konfiguracji itp.
Adresy URL zawartości uwidocznionej
UseDirectoryBrowser
UseStaticFiles
i podlegają ograniczeniom poufności i znaków wielkości liter w podstawowym systemie plików. Na przykład system Windows nie uwzględnia wielkości liter, ale systemy macOS i Linux nie są.ASP.NET Core aplikacje hostowane w usługach IIS używają modułu podstawowego ASP.NET do przekazywania wszystkich żądań do aplikacji, w tym żądań plików statycznych. Program obsługi plików statycznych usług IIS nie jest używany i nie ma szans na obsługę żądań.
Wykonaj następujące kroki w Menedżerze usług IIS, aby usunąć program obsługi plików statycznych usług IIS na poziomie serwera lub witryny internetowej:
- Przejdź do funkcji Moduły .
- Wybierz pozycję StaticFileModule na liście.
- Kliknij przycisk Usuń na pasku bocznym Akcje .
Ostrzeżenie
Jeśli program obsługi plików statycznych usług IIS jest włączony , a moduł ASP.NET Core jest niepoprawnie skonfigurowany, obsługiwane są pliki statyczne. Dzieje się tak, na przykład jeśli plik web.config nie jest wdrożony.
- Umieść pliki kodu, w tym
.cs
i.cshtml
, poza katalogem głównym projektu aplikacji. Dlatego separacja logiczna jest tworzona między zawartością po stronie klienta aplikacji a kodem opartym na serwerze. Zapobiega to wyciekowi kodu po stronie serwera.
Obsługa plików poza witryną wwwroot przez zaktualizowanie elementu IWebHostEnvironment.WebRootPath
Gdy IWebHostEnvironment.WebRootPath jest ustawiona wartość folderu innego niż wwwroot
:
- W środowisku projektowym zasoby statyczne znajdujące się zarówno w programie , jak
wwwroot
i zaktualizowaneIWebHostEnvironment.WebRootPath
są obsługiwane z witrynywwwroot
. - W dowolnym środowisku innym niż programowanie zduplikowane zasoby statyczne są obsługiwane ze zaktualizowanego
IWebHostEnvironment.WebRootPath
folderu.
Rozważmy aplikację internetową utworzoną przy użyciu pustego szablonu internetowego:
Zawiera plik
Index.html
w plikachwwwroot
iwwwroot-custom
.Przy użyciu następującego zaktualizowanego
Program.cs
pliku, który ustawia wartośćWebRootPath = "wwwroot-custom"
:var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = args, // Look for static files in "wwwroot-custom" WebRootPath = "wwwroot-custom" }); var app = builder.Build(); app.UseDefaultFiles(); app.UseStaticFiles(); app.Run();
W poprzednim kodzie żądania do /
:
- W zwracaniu środowiska deweloperskiego
wwwroot/Index.html
- W dowolnym środowisku innym niż zwrot programowania
wwwroot-custom/Index.html
Aby upewnić się, że zasoby z wwwroot-custom
programu zostaną zwrócone, użyj jednego z następujących metod:
Usuń zduplikowane nazwane zasoby w pliku
wwwroot
.Ustaw
"ASPNETCORE_ENVIRONMENT"
wartość naProperties/launchSettings.json
dowolną wartość inną niż"Development"
.Całkowicie wyłącz statyczne zasoby internetowe przez ustawienie
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
w pliku projektu. OSTRZEŻENIE, wyłączenie statycznych zasobów internetowych powoduje wyłączenie Razor bibliotek klas.Dodaj następujący kod JSON do pliku projektu:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
Poniższy kod aktualizuje IWebHostEnvironment.WebRootPath
wartość niezwiązaną z programowaniem, co gwarantuje zwrócenie wwwroot-custom
zduplikowanej zawartości zamiast wwwroot
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Examine Hosting environment: logging value
EnvironmentName = Environments.Staging,
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
app.Environment.IsDevelopment().ToString());
app.UseDefaultFiles();
app.UseStaticFiles();
app.Run();
Dodatkowe zasoby
Autorzy: Rick Anderson i Kirk Larkin
Pliki statyczne, takie jak HTML, CSS, images i JavaScript, to zasoby, które ASP.NET Aplikacja Core domyślnie obsługuje bezpośrednio klientom.
Wyświetl lub pobierz przykładowy kod (jak pobrać)
Obsługa plików statycznych
Pliki statyczne są przechowywane w katalogu głównym projektu. Domyślny katalog to {content root}/wwwroot
, ale można go zmienić za pomocą UseWebRoot metody . Aby uzyskać więcej informacji, zobacz Katalog główny zawartości i Katalog główny sieci Web.
Metoda CreateDefaultBuilder ustawia katalog główny zawartości na bieżący katalog:
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>();
});
}
Poprzedni kod został utworzony za pomocą szablonu aplikacji internetowej.
Pliki statyczne są dostępne za pośrednictwem ścieżki względem katalogu głównego sieci Web. Na przykład szablony projektów aplikacji internetowej zawierają kilka folderów w folderze wwwroot
:
wwwroot
css
js
lib
Rozważ utworzenie folderu wwwroot/images i dodanie wwwroot/images/MyImage.jpg
pliku. Format identyfikatora URI umożliwiający dostęp do pliku w folderze images
to https://<hostname>/images/<image_file_name>
. Na przykład https://localhost:5001/images/MyImage.jpg
Obsługa plików w katalogu głównym sieci Web
Domyślne szablony aplikacji internetowej wywołają metodę UseStaticFiles w Startup.Configure
pliku , która umożliwia obsługę plików statycznych:
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();
});
}
Przeciążenie metody bez UseStaticFiles
parametrów oznacza pliki w katalogu głównym sieci Web jako możliwe. Następujące odwołania wwwroot/images/MyImage.jpg
do znaczników:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
W poprzednim kodzie znak ~/
tyldy wskazuje katalog główny sieci Web.
Obsługa plików spoza katalogu głównego sieci Web
Rozważ hierarchię katalogów, w której pliki statyczne, które mają być obsługiwane, znajdują się poza katalogiem głównym sieci Web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Żądanie może uzyskać dostęp do red-rose.jpg
pliku, konfigurując oprogramowanie pośredniczące pliku statycznego w następujący sposób:
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();
});
}
W poprzednim kodzie hierarchia katalogów MyStaticFiles jest uwidoczniona publicznie za pośrednictwem segmentu identyfikatora URI StaticFiles . Żądanie https://<hostname>/StaticFiles/images/red-rose.jpg
obsługi red-rose.jpg
pliku.
Następujące odwołania MyStaticFiles/images/red-rose.jpg
do znaczników:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Ustawianie nagłówków odpowiedzi HTTP
Obiekt StaticFileOptions może służyć do ustawiania nagłówków odpowiedzi HTTP. Oprócz konfigurowania pliku statycznego obsługującego z katalogu głównego sieci Web następujący kod ustawia Cache-Control
nagłówek:
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();
});
}
Poprzedni kod ustawia maksymalny wiek na 604800 sekund (7 dni).
Autoryzacja pliku statycznego
Szablony ASP.NET Core są wywoływane UseStaticFiles przed wywołaniem metody UseAuthorization. Większość aplikacji jest zgodnie z tym wzorcem. Po wywołaniu oprogramowania pośredniczącego plików statycznych przed oprogramowaniem pośredniczącym autoryzacji:
- W plikach statycznych nie są wykonywane kontrole autoryzacji.
- Pliki statyczne obsługiwane przez oprogramowanie pośredniczące plików statycznych, takie jak w obszarze
wwwroot
, są publicznie dostępne.
Aby obsługiwać pliki statyczne na podstawie autoryzacji:
- Przechowuj je poza elementem
wwwroot
. - Wywołaj metodę
UseStaticFiles
, określając ścieżkę po wywołaniu metodyUseAuthorization
. - Ustaw zasady autoryzacji rezerwowej.
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.
W poprzednim kodzie zasady autoryzacji rezerwowej wymagają uwierzytelnienia wszystkich użytkowników. Punkty końcowe, takie jak kontrolery, Razor strony itp., które określają własne wymagania dotyczące autoryzacji, nie korzystają z zasad autoryzacji rezerwowej. Na przykład Razor strony, kontrolery lub metody akcji z zastosowanym atrybutem [AllowAnonymous]
autoryzacji lub [Authorize(PolicyName="MyPolicy")]
użyj ich, a nie zasad autoryzacji rezerwowej.
RequireAuthenticatedUser dodaje DenyAnonymousAuthorizationRequirement do bieżącego wystąpienia, co wymusza uwierzytelnienie bieżącego użytkownika.
Zasoby statyczne w obszarze wwwroot
są publicznie dostępne, ponieważ domyślne oprogramowanie pośredniczące plików statycznych (app.UseStaticFiles();
) jest wywoływane przed UseAuthentication
. Zasoby statyczne w folderze MyStaticFiles wymagają uwierzytelniania. Przykładowy kod pokazuje to.
Alternatywną metodą udostępniania plików na podstawie autoryzacji jest:
- Przechowuj je poza katalogami
wwwroot
i dostępnymi dla oprogramowania pośredniczącego plików statycznych. - Za pomocą metody akcji, do której jest stosowana autoryzacja FileResult i zwraca obiekt:
[Authorize]
public IActionResult BannerImage()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
Przeglądanie katalogów
Przeglądanie katalogów umożliwia wyświetlanie listy katalogów w określonych katalogach.
Przeglądanie katalogów jest domyślnie wyłączone ze względów bezpieczeństwa. Aby uzyskać więcej informacji, zobacz Zagadnienia dotyczące zabezpieczeń plików statycznych.
Włącz przeglądanie katalogów za pomocą:
- AddDirectoryBrowser w pliku
Startup.ConfigureServices
. - UseDirectoryBrowser w pliku
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();
});
}
Powyższy kod umożliwia przeglądanie katalogów folderu wwwroot/images przy użyciu adresu URL https://<hostname>/MyImages
, z linkami do każdego pliku i folderu:
Obsługa dokumentów domyślnych
Ustawienie strony domyślnej zapewnia odwiedzającym punkt początkowy w witrynie. Aby obsłużyć plik domyślny bez wwwroot
konieczności uwzględnienia nazwy pliku przez adres URL żądania, wywołaj metodę UseDefaultFiles :
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
musi być wywoływana przed UseStaticFiles
udostępnieniem pliku domyślnego. UseDefaultFiles
jest autorem adresu URL, który nie obsługuje pliku.
Za pomocą polecenia UseDefaultFiles
żądania do folderu w wwwroot
wyszukiwaniu:
default.htm
default.html
index.htm
index.html
Pierwszy plik znaleziony na liście jest obsługiwany tak, jakby żądanie zawierało nazwę pliku. Adres URL przeglądarki nadal odzwierciedla żądany identyfikator URI.
Poniższy kod zmienia domyślną nazwę pliku na mydefault.html
:
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
Poniższy kod przedstawia Startup.Configure
powyższy kod:
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 dla dokumentów domyślnych
UseFileServer łączy funkcje UseStaticFiles
, UseDefaultFiles
i opcjonalnie UseDirectoryBrowser
.
Wywołaj metodę app.UseFileServer
w celu włączenia obsługi plików statycznych i pliku domyślnego. Przeglądanie katalogów nie jest włączone. Poniższy kod przedstawia kod Startup.Configure
z elementem UseFileServer
:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Poniższy kod umożliwia obsługę plików statycznych, pliku domyślnego i przeglądania katalogów:
app.UseFileServer(enableDirectoryBrowsing: true);
Poniższy kod przedstawia Startup.Configure
powyższy kod:
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();
});
}
Rozważ następującą hierarchię katalogów:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
Poniższy kod umożliwia obsługę plików statycznych, pliku domyślnego i przeglądania katalogów:MyStaticFiles
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDirectoryBrowser();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(); // For the wwwroot folder.
// using Microsoft.Extensions.FileProviders;
// using System.IO;
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
AddDirectoryBrowser element musi być wywoływany, EnableDirectoryBrowsing
gdy wartość właściwości to true
.
Korzystając z hierarchii plików i poprzedniego kodu, adresy URL są rozpoznawane w następujący sposób:
Identyfikator URI | Response |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Jeśli w katalogu MyStaticFiles nie istnieje żaden plik o nazwie domyślnej, https://<hostname>/StaticFiles
zwraca listę katalogów z linkami, które można kliknąć:
UseDefaultFiles i UseDirectoryBrowser wykonaj przekierowanie po stronie klienta z docelowego identyfikatora URI bez /
końcowego identyfikatora URI z końcowym /
identyfikatorem URI. Na przykład od https://<hostname>/StaticFiles
do https://<hostname>/StaticFiles/
. Względne adresy URL w katalogu StaticFiles są nieprawidłowe bez końcowego ukośnika (/
).
FileExtensionContentTypeProvider
Klasa FileExtensionContentTypeProvider zawiera Mappings
właściwość, która służy jako mapowanie rozszerzeń plików na typy zawartości MIME. W poniższym przykładzie kilka rozszerzeń plików jest mapowanych na znane typy MIME. Rozszerzenie .rtf jest zastępowane i .mp4 jest usuwane:
// 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"
});
Poniższy kod przedstawia Startup.Configure
powyższy kod:
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();
});
}
Zobacz Typy zawartości MIME.
Niestandardowe typy zawartości
Oprogramowanie pośredniczące plików statycznych rozumie prawie 400 znanych typów zawartości plików. Jeśli użytkownik żąda pliku z nieznanym typem pliku, oprogramowanie static file middleware przekazuje żądanie do następnego oprogramowania pośredniczącego w potoku. Jeśli żadne oprogramowanie pośredniczące nie obsługuje żądania, zostanie zwrócona odpowiedź 404 Nie znaleziono . Jeśli przeglądanie katalogów jest włączone, link do pliku jest wyświetlany na liście katalogów.
Poniższy kod umożliwia obsługę nieznanych typów i renderuje nieznany plik jako obraz:
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
Poniższy kod przedstawia Startup.Configure
powyższy kod:
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();
});
}
W poprzednim kodzie żądanie pliku o nieznanym typie zawartości jest zwracane jako obraz.
Ostrzeżenie
ServeUnknownFileTypes Włączenie jest zagrożeniem bezpieczeństwa. Jest on domyślnie wyłączony, a jego użycie jest odradzane. FileExtensionContentTypeProvider zapewnia bezpieczniejszą alternatywę dla obsługi plików z niestandardowymi rozszerzeniami.
Obsługa plików z wielu lokalizacji
UseStaticFiles
i UseFileServer
domyślnie do dostawcy plików wskazującego wartość .wwwroot
Dodatkowe wystąpienia UseStaticFiles
programu i UseFileServer
mogą być udostępniane innym dostawcom plików w celu udostępniania plików z innych lokalizacji. Aby uzyskać więcej informacji, zobacz ten problem w serwisie GitHub.
Zagadnienia dotyczące zabezpieczeń plików statycznych
Ostrzeżenie
UseDirectoryBrowser
i UseStaticFiles
może wyciekać tajemnice. Wyłączenie przeglądania katalogów w środowisku produkcyjnym jest zdecydowanie zalecane. Dokładnie sprawdź, które katalogi są włączone za pośrednictwem programu UseStaticFiles
lub UseDirectoryBrowser
. Cały katalog i jego podkatalog stają się publicznie dostępne. Przechowuj pliki odpowiednie do obsługi publicznej w dedykowanym katalogu, takim jak <content_root>/wwwroot
. Oddziel te pliki od widoków MVC, Razor stron, plików konfiguracji itp.
Adresy URL zawartości uwidocznionej
UseDirectoryBrowser
UseStaticFiles
i podlegają ograniczeniom poufności i znaków wielkości liter w podstawowym systemie plików. Na przykład system Windows nie uwzględnia wielkości liter, ale systemy macOS i Linux nie są.ASP.NET Core aplikacje hostowane w usługach IIS używają modułu podstawowego ASP.NET do przekazywania wszystkich żądań do aplikacji, w tym żądań plików statycznych. Program obsługi plików statycznych usług IIS nie jest używany i nie ma szans na obsługę żądań.
Wykonaj następujące kroki w Menedżerze usług IIS, aby usunąć program obsługi plików statycznych usług IIS na poziomie serwera lub witryny internetowej:
- Przejdź do funkcji Moduły .
- Wybierz pozycję StaticFileModule na liście.
- Kliknij przycisk Usuń na pasku bocznym Akcje .
Ostrzeżenie
Jeśli program obsługi plików statycznych usług IIS jest włączony , a moduł ASP.NET Core jest niepoprawnie skonfigurowany, obsługiwane są pliki statyczne. Dzieje się tak, na przykład jeśli plik web.config nie jest wdrożony.
- Umieść pliki kodu, w tym
.cs
i.cshtml
, poza katalogem głównym projektu aplikacji. Dlatego separacja logiczna jest tworzona między zawartością po stronie klienta aplikacji a kodem opartym na serwerze. Zapobiega to wyciekowi kodu po stronie serwera.