Pliki statyczne w ASP.NET Core
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz artykuł w wersji .NET 9.
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ę artykułu .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.
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 Główny katalog 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łują metodę UseStaticFiles w Program.cs
, co 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 bezparametrowej oznacza pliki w katalogu głównym sieci Web jako udostępniane. Następujące odniesienia do znaczników wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
W poprzednim znaczniku znak tyldy ~
wskazuje na katalog główny sieci web.
Serwowanie plików spoza katalogu głównego 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 pliku red-rose.jpg
, konfigurując oprogramowanie pośredniczące do obsługi plików statycznych 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
dotyczy pliku red-rose.jpg
.
Następujące odwołania do znaczników MyStaticFiles/images/red-rose.jpg
:
<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 serwowania plików statycznych 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 wywołują UseStaticFiles przed wywołaniem UseAuthorization. Większość aplikacji podąża za tym wzorcem. Gdy oprogramowanie pośredniczące plików statycznych jest wywoływane przed oprogramowaniem pośredniczącym autoryzacji:
- W plikach statycznych nie są wykonywane kontrole autoryzacji.
- Pliki statyczne obsługiwane przez middleware do obsługi 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 zapasową politykę autoryzacji.
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]
lub [Authorize(PolicyName="MyPolicy")]
używają tego atrybutu zamiast rezerwowej polityki autoryzacji.
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
wwwroot
oraz wszystkimi katalogami, do których ma dostęp oprogramowanie pośredniczące do obsługi plików statycznych.Serwuj je za pomocą metody akcji, do której stosowana jest autoryzacja, i zwracaj obiekt FileResult.
[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 z wwwroot
bez potrzeby uwzględniania nazwy pliku w adresie 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łana przed UseStaticFiles
aby obsłużyć plik domyślny.
UseDefaultFiles
jest narzędziem do przepisywania adresów URL, które nie dostarcza pliku.
Za pomocą UseDefaultFiles
żądania do folderu w wwwroot
wyszukują:
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 musi być wywoływane, gdy wartość właściwości EnableDirectoryBrowsing
wynosi true
.
Korzystając z poprzedniej hierarchii plików i kodu, adresy URL są rozpoznawane w następujący sposób:
Identyfikator URI | Odpowiedź |
---|---|
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 wykonują przekierowanie po stronie klienta z docelowego URI bez końcowego /
do docelowego URI z końcowym /
. Na przykład od https://<hostname>/StaticFiles
do https://<hostname>/StaticFiles/
. Względne adresy URL w katalogu StaticFiles są nieprawidłowe bez ukośnika na końcu (/
), chyba że 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, oprogramowanie pośredniczące do obsługi plików statycznych przekazuje żądanie do następnego oprogramowania pośredniczącego w sekwencji przetwarzania. 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ących na wwwroot
. Dodatkowe instancje UseStaticFiles
i UseFileServer
mogą być udostępniane innym dostawcom plików w celu serwowania plików z innych lokalizacji. Poniższy przykład wywołuje UseStaticFiles
dwa razy, aby obsługiwać pliki z wwwroot
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:
-
/MyStaticFiles/image3.png
plik jest wyświetlany. -
Pomocnik tagu obrazuAppendVersion nie jest stosowany, ponieważ pomocnicy tagów zależą od WebRootFileProvider.
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 App, zobacz statyczne pliki Blazor ASP.NET Core.
Zagadnienia dotyczące zabezpieczeń plików statycznych
Ostrzeżenie
UseDirectoryBrowser
i UseStaticFiles
mogą wyciekać tajemnice. Wyłączenie przeglądania katalogów w środowisku produkcyjnym jest zdecydowanie zalecane. Dokładnie sprawdź, które katalogi są włączone za pomocą 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 dla zawartości ujawnionej za pomocą
UseDirectoryBrowser
iUseStaticFiles
podlegają ograniczeniom związanym z wrażliwością na wielkość liter i znaków w podstawowym systemie plików. Na przykład system Windows jest nieczuły na wielkość liter, ale systemy macOS i Linux uwzględniają wielkość liter.Aplikacje ASP.NET Core hostowane w IIS używają modułu ASP.NET Core do przekazywania wszystkich żądań do aplikacji, w tym żądań plików statycznych. Obsługiwacz plików statycznych w IIS nie jest używany i nie może obsługiwać żą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 w usługach IIS jest włączony i moduł ASP.NET Core jest niepoprawnie skonfigurowany, pliki statyczne mogą być obsługiwane. 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.
Udostępnianie plików spoza wwwroot przez aktualizację IWebHostEnvironment.WebRootPath
Gdy IWebHostEnvironment.WebRootPath jest ustawiony na folder inny niż wwwroot
:
- W środowisku projektowym zasoby statyczne znajdujące się zarówno w
wwwroot
, jak i w zaktualizowanymIWebHostEnvironment.WebRootPath
są obsługiwane z serwerawwwroot
. - W każdym środowisku innym niż tworzenie, zduplikowane zasoby statyczne są serwowane z zaktualizowanego folderu
IWebHostEnvironment.WebRootPath
.
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 środowisku deweloperskim zwróć
wwwroot/Index.html
- W dowolnym środowisku innym niż programistyczne zwróć
wwwroot-custom/Index.html
Aby upewnić się, że zasoby z wwwroot-custom
zostaną zwrócone, użyj jednego z następujących metod:
Usuń zduplikowane nazwane zasoby w
wwwroot
.Ustaw
"ASPNETCORE_ENVIRONMENT"
wProperties/launchSettings.json
na 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
na wartość niezwiązaną z programowaniem, co gwarantuje, że zduplikowana zawartość zostanie zwrócona z wwwroot-custom
zamiast z 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 oraz 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
Udostępnianie plików w katalogu głównym sieci Web
Domyślne szablony aplikacji internetowej wywołają metodę UseStaticFiles w Program.cs
, co 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 bezparametrowej oznacza pliki w katalogu głównym sieci Web jako dostępne do serwowania. Następujące referencje do znaczników wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Znak tyldy ~
w poprzednim znaczniku wskazuje na root sieciowy.
Serwowanie plików spoza katalogu głównego serwera WWW
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 pliku red-rose.jpg
poprzez skonfigurowanie pośrednictwa dla plików statycznych 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 do https://<hostname>/StaticFiles/images/red-rose.jpg
dostarcza plik red-rose.jpg
.
Następujące odwołania do znaczników MyStaticFiles/images/red-rose.jpg
:
<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 serwowania plików statycznych z katalogu głównego w 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 wywołują UseStaticFiles przed wywołaniem UseAuthorization. Większość aplikacji podąża za tym wzorcem. Gdy oprogramowanie pośredniczące plików statycznych jest wywoływane przed oprogramowaniem pośredniczącym autoryzacji:
- W plikach statycznych nie są wykonywane kontrole autoryzacji.
- Pliki statyczne obsługiwane przez middleware 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 zapasowe zasady autoryzacji.
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 zastosowaniem [AllowAnonymous]
lub [Authorize(PolicyName="MyPolicy")]
używają przypisanego atrybutu autoryzacji zamiast rezerwowej polityki autoryzacji.
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 tymi, do których dostęp ma oprogramowanie pośredniczące do plików statycznych. - Serwuj je za pomocą metody akcji, do której zastosowano autoryzację, i zwróć obiekt FileResult.
[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ć domyślny plik z wwwroot
bez konieczności uwzględniania nazwy pliku w żądaniu URL, 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 narzędziem do przepisywania adresów URL, który nie serwuje pliku.
W przypadku UseDefaultFiles
, żądania do folderu w wwwroot
wyszukiwane są:
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 musi być wywoływany, gdy wartość właściwości EnableDirectoryBrowsing
to true
.
Korzystając z poprzedniej hierarchii plików i kodu, adresy URL są rozpoznawane w następujący sposób:
Identyfikator URI | Odpowiedź |
---|---|
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 wykonują przekierowanie po stronie klienta z docelowego URI bez końcowego /
do docelowego URI z końcowym /
. 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 używana jest opcja DefaultFilesOptionsRedirectToAppendTrailingSlash.
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 używają dostawcy plików wskazującego na wwwroot
. Dodatkowe wystąpienia UseStaticFiles
i UseFileServer
mogą być dostarczane przez innych dostawców usług plikowych do obsługi plików z innych lokalizacji. Poniższy przykład wywołuje UseStaticFiles
dwa razy, aby obsługiwać pliki z wwwroot
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:
- Wyświetlany jest
/MyStaticFiles/image3.png
plik. -
Pomocnicy znaczników obrazówAppendVersion nie są stosowane, ponieważ pomocnicy znaczników zależą od WebRootFileProvider.
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
mogą wyciekać tajemnice. Wyłączenie przeglądania katalogów w środowisku produkcyjnym jest zdecydowanie zalecane. Dokładnie sprawdź, które katalogi są włączone przez 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 dla zawartości udostępnionej za pomocą
UseDirectoryBrowser
iUseStaticFiles
podlegają rozróżnieniu wielkości liter oraz ograniczeniom znaków w podstawowym systemie plików. Na przykład, system Windows jest niewrażliwy na wielkość liter, ale macOS i Linux są wrażliwe.Aplikacje ASP.NET Core hostowane w usługach IIS używają modułu ASP.NET Core 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 może obsługiwać żą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.
Serwowanie plików spoza katalogu wwwroot przez zaktualizowanie parametru IWebHostEnvironment.WebRootPath
Gdy IWebHostEnvironment.WebRootPath jest ustawiony na folder inny niż wwwroot
:
- W środowisku projektowym zasoby statyczne znajdujące się zarówno w
wwwroot
, jak i w zaktualizowanymIWebHostEnvironment.WebRootPath
są obsługiwane zwwwroot
. - W każdym środowisku innym niż deweloperskie, duplikaty zasobów statycznych są obsługiwane z zaktualizowanego folderu
IWebHostEnvironment.WebRootPath
.
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 składane do /
:
- W środowisku deweloperskim zwróć
wwwroot/Index.html
- W dowolnym środowisku innym niż środowisko programistyczne zwróć
wwwroot-custom/Index.html
Aby upewnić się, że zasoby z wwwroot-custom
zostaną zwrócone, użyj jednego z następujących podejść:
Usuń zduplikowane nazwane zasoby w
wwwroot
.Ustaw
"ASPNETCORE_ENVIRONMENT"
wProperties/launchSettings.json
na 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 Witryny.
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łują metodę UseStaticFiles w Startup.Configure
, co 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 bezparametrowej oznacza pliki w głównym katalogu sieciowym jako dostępne. Następujące odwołania do znaczników: wwwroot/images/MyImage.jpg
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
W poprzednim kodzie tylda ~/
wskazuje na korzeń webowy.
Serwowanie 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 pliku red-rose.jpg
, konfigurując oprogramowanie pośredniczące dla plików statycznych 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 do https://<hostname>/StaticFiles/images/red-rose.jpg
obsługuje plik red-rose.jpg
.
Następujący znacznik odnosi się do MyStaticFiles/images/red-rose.jpg
:
<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 obsługi plików statycznych z katalogu głównego serwera, następujący kod ustawia 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 wywołują UseStaticFiles przed wywołaniem UseAuthorization. Większość aplikacji podąża za tym wzorcem. Gdy oprogramowanie pośredniczące plików statycznych jest wywoływane przed oprogramowaniem pośredniczącym autoryzacji:
- W plikach statycznych nie są wykonywane kontrole autoryzacji.
- Oprogramowanie pośredniczące (Middleware) do obsługi plików statycznych, takie jak te w obszarze
wwwroot
, jest 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 zapasowej.
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 używają zastosowanego atrybutu autoryzacji [AllowAnonymous]
lub [Authorize(PolicyName="MyPolicy")]
zamiast 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
wwwroot
oraz poza dowolnym katalogiem dostępnym dla oprogramowania pośredniczącego plików statycznych. - Podawaj je za pomocą metody akcji, do której stosuje się autoryzację, i zwróć obiekt FileResult.
[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 z wwwroot
bez konieczności wymagania, aby adres URL żądania zawierał nazwę pliku, 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łana przed UseStaticFiles
, aby udostępnić plik domyślny.
UseDefaultFiles
jest narzędziem do przepisywania adresów URL, które nie serwuje pliku.
Za pomocą UseDefaultFiles
, żądania do folderu w wwwroot
wyszukują:
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
wraz z poprzednim kodem.
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
z poprzednim kodem:
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 musi być wywołany, gdy wartość właściwości EnableDirectoryBrowsing
to true
.
Korzystając z hierarchii plików i poprzedniego kodu, adresy URL są rozpoznawane w następujący sposób:
Identyfikator URI | Odpowiedź |
---|---|
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 wykonują przekierowanie po stronie klienta z docelowego URI bez końcowego /
na docelowy URI z końcowym /
. 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"
});
Oto kod pokazujący Startup.Configure
wraz z poprzedzającym kodem.
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, pośrednik plików statycznych przekazuje żądanie do kolejnego pośrednika 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
razem z wcześniejszym kodem:
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 ustawiają się na dostawcę plików wskazującego na wwwroot
. Dodatkowe wystąpienia UseStaticFiles
i UseFileServer
mogą być dostarczone z innymi dostawcami plików, aby udostępniać pliki 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
mogą wyciekać tajemnice. Wyłączenie przeglądania katalogów w środowisku produkcyjnym jest zdecydowanie zalecane. Dokładnie sprawdź, które katalogi są włączone przez 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 dla zawartości przedstawionej za pomocą
UseDirectoryBrowser
orazUseStaticFiles
podlegają ograniczeniom dotyczącym wielkości liter i znaków właściwych dla podstawowego systemu plików. Na przykład system Windows ignoruje wielkość liter, ale systemy macOS i Linux ją uwzględniają.ASP.NET Core aplikacje hostowane w IIS używają modułu ASP.NET Core 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 może obsługiwać żą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, pliki statyczne zostaną obsłużone. 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.