Statische bestanden in ASP.NET Core
Notitie
Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-versie van dit artikelvoor de huidige release.
Waarschuwing
Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie de .NET- en .NET Core-ondersteuningsbeleidvoor meer informatie. Zie de .NET 9-versie van dit artikelvoor de huidige release.
Belangrijk
Deze informatie heeft betrekking op een pre-releaseproduct dat aanzienlijk kan worden gewijzigd voordat het commercieel wordt uitgebracht. Microsoft geeft geen garanties, uitdrukkelijk of impliciet, met betrekking tot de informatie die hier wordt verstrekt.
Zie de .NET 9-versie van dit artikelvoor de huidige release.
Door Rick Anderson
Statische bestanden, zoals HTML, CSS, afbeeldingen en JavaScript, zijn assets die een ASP.NET Core-app standaard rechtstreeks aan clients dienen.
Zie ASP.NET Core Blazor statische bestandenvoor Blazor richtlijnen voor statische bestanden, die worden toegevoegd aan of vervangen door de richtlijnen in dit artikel.
Statische bestanden verwerken
Statische bestanden worden opgeslagen in de webhoofdmap van het project map. De standaardmap is {content root}/wwwroot
, maar kan worden gewijzigd met de methode UseWebRoot. Voor meer informatie, zie Hoofdmap van inhoud en Webhoofdmap.
Met de methode CreateBuilder wordt de hoofdmap van de inhoud ingesteld op de huidige map:
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();
Statische bestanden zijn toegankelijk via een pad relatief aan de webhoofdmap. De Web Application projectsjablonen bevatten bijvoorbeeld verschillende mappen in de map wwwroot
:
wwwroot
css
js
lib
Overweeg een app met het wwwroot/images/MyImage.jpg
-bestand. De URI-indeling voor toegang tot een bestand in de map images
is https://<hostname>/images/<image_file_name>
. Bijvoorbeeld https://localhost:5001/images/MyImage.jpg
MapStaticAssets
Voor het maken van krachtige web-apps is het optimaliseren van assetlevering in de browser vereist. Mogelijke optimalisaties zijn:
- Lever een opgegeven asset eenmaal totdat het bestand verandert of de browser de cache leegt. Stel de ETag koptekst in.
- Voorkomen dat de browser oude of verouderde assets gebruikt nadat een app is bijgewerkt. Stel de koptekst Laatst gewijzigd in.
- Stel de juiste caching headers in.
- Gebruik cache-middleware .
- Gebruik indien mogelijk gecomprimeerde versies van de assets.
- Gebruik een CDN- om de assets dichter bij de gebruiker te leveren.
- Minimaliseer de grootte van assets die aan de browser worden geleverd. Deze optimalisatie omvat geen minificatie.
- Integreert de informatie die wordt verzameld over statische webassets tijdens het build- of publicatieproces met een runtimebibliotheek die deze informatie verwerkt om het bestand te optimaliseren dat aan de browser wordt geleverd.
- Er zijn routeringseindpuntconventies die de levering van statische assets in een app optimaliseren. Het is ontworpen om te werken met alle UI-frameworks, waaronder Blazor, Razor Pagina's en MVC.
UseStaticFiles
dient ook statische bestanden, maar biedt niet hetzelfde optimalisatieniveau als MapStaticAssets
. Voor een vergelijking van UseStaticFiles
en MapStaticAssets
, zie Het leveren van statische webassets optimaliseren .
Bestanden serveren in de hoofdmap van het web
Met de standaardweb-app-sjablonen wordt de methode MapStaticAssets in Program.cs
aangeroepen, waarmee statische bestanden kunnen worden verwerkt:
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();
De parameterloze UseStaticFiles
method overload markeert de bestanden in de webroot als serveerbaar. De volgende markeringen verwijzen wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
In de voorgaande markering verwijst het tilde-teken ~
naar de webroot.
Bestanden buiten de webroot aanbieden
Overweeg een mappenstructuur waarin de statische bestanden die geleverd moeten worden zich buiten de webhoofdmap bevinden.
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Een verzoek kan toegang krijgen tot het red-rose.jpg
-bestand door de Static File Middleware als volgt te configureren:
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();
In de voorgaande code wordt de hiërarchie van de map MyStaticFiles publiekelijk beschikbaar gemaakt via het StaticFiles URI-segment. Een verzoek aan https://<hostname>/StaticFiles/images/red-rose.jpg
bedient het red-rose.jpg
-bestand.
De volgende markeringen verwijzen MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Zie Bestanden vanaf meerdere locaties bedienenals u bestanden van meerdere locaties wilt gebruiken.
HTTP-antwoordheaders instellen
Een StaticFileOptions-object kan worden gebruikt om HTTP-antwoordheaders in te stellen. Naast het configureren van statische bestanden vanuit de webroot, stelt de volgende code de header Cache-Control in.
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();
De voorgaande code maakt statische bestanden openbaar beschikbaar in de lokale cache voor één week.
Autorisatie van statische bestanden
De ASP.NET Core-sjablonen roepen MapStaticAssets aan voordat u UseAuthorizationaanroept. De meeste apps volgen dit patroon. Wanneer de Static File Middleware wordt aangeroepen vóór de autorisatie-middleware:
- Er worden geen autorisatiecontroles uitgevoerd op de statische bestanden.
- Statische bestanden die worden geleverd door de Static File Middleware, zoals die onder
wwwroot
, zijn openbaar toegankelijk.
Statische bestanden verwerken op basis van autorisatie:
- Sla ze buiten
wwwroot
op. -
UseStaticFiles
aanroepen, een pad opgeven na het aanroepen vanUseAuthorization
. - Stel het reserve-autorisatiebeleid in.
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();
In de voorgaande code vereist het autorisatiebeleid voor terugval alle gebruikers moeten worden geverifieerd. Eindpunten zoals controllers, Razor Pagina's, enzovoort, die hun eigen autorisatievereisten opgeven, gebruiken het standaard autorisatiebeleid niet. Zo gebruiken Razor pagina's, controllers of actiemethoden met [AllowAnonymous]
of [Authorize(PolicyName="MyPolicy")]
het toegepaste autorisatiekenmerk in plaats van het autorisatiebeleid voor terugval.
RequireAuthenticatedUser voegt DenyAnonymousAuthorizationRequirement toe aan het huidige exemplaar, waardoor de huidige gebruiker wordt geverifieerd.
Statische assets onder wwwroot
zijn openbaar toegankelijk omdat de standaard statische bestands-middleware (app.UseStaticFiles();
) wordt aangeroepen vóór UseAuthentication
. Voor statische assets in de map MyStaticFiles is verificatie vereist. De voorbeeldcode laat dit zien.
Een alternatieve benadering voor het verwerken van bestanden op basis van autorisatie is het volgende:
Bewaar ze buiten
wwwroot
en elke map die toegankelijk is voor de Static File Middleware.Serveer ze via een actiemethode waarop autorisatie wordt toegepast en retourneer een FileResult-object:
[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"); } }
Voor de voorgaande benadering is een pagina of eindpunt per bestand vereist. De volgende code retourneert bestanden of uploadt bestanden voor geverifieerde gebruikers:
app.MapGet("/files/{fileName}", IResult (string fileName) =>
{
var filePath = GetOrCreateFilePath(fileName);
if (File.Exists(filePath))
{
return TypedResults.PhysicalFile(filePath, fileDownloadName: $"{fileName}");
}
return TypedResults.NotFound("No file found with the supplied file name");
})
.WithName("GetFileByName")
.RequireAuthorization("AuthenticatedUsers");
app.MapPost("/files",
async (IFormFile file, LinkGenerator linker, HttpContext context) =>
{
// Don't rely on the file.FileName as it is only metadata that can be
// manipulated by the end-user. See the `Utilities.IsFileValid` method that
// takes an IFormFile and validates its signature within the
// AllowedFileSignatures
var fileSaveName = Guid.NewGuid().ToString("N")
+ Path.GetExtension(file.FileName);
await SaveFileWithCustomFileName(file, fileSaveName);
context.Response.Headers.Append("Location",
linker.GetPathByName(context, "GetFileByName",
new { fileName = fileSaveName}));
return TypedResults.Ok("File Uploaded Successfully!");
})
.RequireAuthorization("AdminsOnly");
app.Run();
IFormFile in het voorgaande voorbeeld maakt gebruik van een geheugenbuffer voor het uploaden. Voor het verwerken van grote bestanden wordt streaming gebruikt. Zie Grote bestanden uploaden met streaming.
Zie de map StaticFileAuth GitHub voor het volledige voorbeeld.
Bladeren door directories
Het bladeren door directories staat de weergave van directory-inhoud binnen opgegeven directories toe.
Bladeren door mappen is standaard uitgeschakeld om veiligheidsredenen. Zie Beveiligingsoverwegingen voor statische bestandenvoor meer informatie.
Bladeren door mappen inschakelen met AddDirectoryBrowser en 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();
Met de voorgaande code kunt u bladeren door mappen van de wwwroot/images map met behulp van de URL https://<hostname>/MyImages
, met koppelingen naar elk bestand en elke map:
AddDirectoryBrowser
voegt services toe die vereist zijn voor de mapnavigatie-middleware, waaronder HtmlEncoder. Deze services kunnen worden toegevoegd door andere aanroepen, zoals AddRazorPages, maar we raden u aan AddDirectoryBrowser
aan te roepen om ervoor te zorgen dat de services in alle apps worden toegevoegd.
Standaarddocumenten serveren
Het instellen van een standaardpagina biedt bezoekers een startpunt op een site. Als u een standaardbestand van wwwroot
wilt leveren zonder dat de aanvraag-URL de naam van het bestand moet opnemen, roept u de UseDefaultFiles methode aan:
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
moet worden aangeroepen voordat UseStaticFiles
het standaardbestand moet leveren.
UseDefaultFiles
is een URL-rewriter die het bestand niet dient.
Met UseDefaultFiles
worden verzoeken naar een map in wwwroot
uitgevoerd voor het zoeken naar:
default.htm
default.html
index.htm
index.html
Het eerste bestand uit de lijst wordt geleverd alsof de aanvraag de naam van het bestand bevat. De browser-URL blijft de aangevraagde URI weerspiegelen. Bijvoorbeeld, in de voorbeeld-app, dient een aanvraag voor https://localhost:<port>/def/
default.html
uit wwwroot/def
.
Met de volgende code wordt de standaardbestandsnaam gewijzigd in mydefault.html
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
UseFileServer voor standaarddocumenten
UseFileServer combineert de functionaliteit van UseStaticFiles
, UseDefaultFiles
en eventueel UseDirectoryBrowser
.
Roep app.UseFileServer
aan om het leveren van statische bestanden en het standaardbestand in te schakelen. Bladeren in mappen is niet ingeschakeld:
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();
Met de volgende code kunt u statische bestanden, het standaardbestand en bladeren door mappen uitvoeren:
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();
Houd rekening met de volgende maphiërarchie:
wwwroot
css
images
js
MyStaticFiles
defaultFiles
default.html
image3.png
images
MyImage.jpg
Met de volgende code kunt u statische bestanden, het standaardbestand en het bladeren door mappen van MyStaticFiles
inschakelen:
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 moet worden aangeroepen wanneer de eigenschapswaarde van de EnableDirectoryBrowsing
is true
.
Met behulp van de voorgaande bestandshiërarchie en code worden URL's als volgt omgezet:
URI | Antwoord |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
lijst van directory's |
https://<hostname>/StaticFiles/defaultFiles |
MyStaticFiles/defaultFiles/default.html |
https://<hostname>/StaticFiles/defaultFiles/image3.png |
MyStaticFiles/defaultFiles//image3.png |
Als er geen standaardbestand met de naam bestaat in de map MyStaticFiles, retourneert https://<hostname>/StaticFiles
de mapvermelding met klikbare koppelingen:
UseDefaultFiles en UseDirectoryBrowser voeren aan de clientzijde een omleiding uit van de doel-URI zonder /
naar de doel-URI met een afsluitende /
. Bijvoorbeeld van https://<hostname>/StaticFiles
tot https://<hostname>/StaticFiles/
. Relatieve URL's in de StaticFiles map zijn ongeldig zonder een afsluitende slash (/
) tenzij de RedirectToAppendTrailingSlash optie van DefaultFilesOptions wordt gebruikt.
FileExtensionContentTypeProvider
De FileExtensionContentTypeProvider-klasse bevat een Toewijzingen eigenschap die fungeert als toewijzing van bestandsextensies aan MIME-inhoudstypen. In het volgende voorbeeld worden verschillende bestandsextensies toegewezen aan bekende MIME-typen. De .rtf-extensie wordt vervangen en .mp4 wordt verwijderd:
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();
Zie MIME-inhoudstypen.
Niet-standaardinhoudstypen
De Static File Middleware begrijpt bijna 400 bekende bestandsinhoudstypen. Als de gebruiker een bestand met een onbekend bestandstype aanvraagt, geeft de Static File Middleware de aanvraag door aan de volgende middleware in de pijplijn. Als er geen middleware de aanvraag verwerkt, wordt een 404 Niet gevonden antwoord geretourneerd. Als bladeren in mappen is ingeschakeld, wordt een koppeling naar het bestand weergegeven in een lijst met mappen.
Met de volgende code kunt u onbekende typen leveren en het onbekende bestand weergeven als een afbeelding:
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();
Met de voorgaande code wordt een aanvraag voor een bestand met een onbekend inhoudstype geretourneerd als een afbeelding.
Waarschuwing
Het inschakelen van ServeUnknownFileTypes is een beveiligingsrisico. Het is standaard uitgeschakeld en het gebruik ervan wordt afgeraden. FileExtensionContentTypeProvider biedt een veiliger alternatief voor bestanden met niet-standaardextensies.
Bestanden vanaf meerdere locaties leveren
Houd rekening met de volgende Razor pagina waarop het /MyStaticFiles/image3.png
-bestand wordt weergegeven:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
en UseFileServer
verwijzen standaard naar de bestandsprovider die naar wwwroot
wijst. Extra exemplaren van UseStaticFiles
en UseFileServer
kunnen worden geleverd met andere bestandsproviders om bestanden van andere locaties te verwerken. In het volgende voorbeeld wordt UseStaticFiles
twee keer aanroepen om bestanden uit zowel wwwroot
als MyStaticFiles
te verwerken:
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Gebruik de voorgaande code:
- Het
/MyStaticFiles/image3.png
-bestand wordt weergegeven. - De afbeeldingslabels AppendVersion worden niet toegepast omdat de Tag Helpers afhankelijk zijn van WebRootFileProvider.
WebRootFileProvider
is niet bijgewerkt om de mapMyStaticFiles
op te nemen.
Met de volgende code wordt de WebRootFileProvider
bijgewerkt, waardoor de Helper voor afbeeldingentags een versie kan opgeven:
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();
Notitie
De voorgaande benadering is van toepassing op Razor Pagina's en MVC-apps. Zie ASP.NET Core Blazor statische bestandenvoor richtlijnen die van toepassing zijn op Blazor Web Apps.
Beveiligingsoverwegingen voor statische bestanden
Waarschuwing
UseDirectoryBrowser
en UseStaticFiles
kunnen geheimen lekken. Het uitschakelen van bladeren door mappen in productie wordt ten zeerste aanbevolen. Controleer zorgvuldig welke mappen zijn ingeschakeld via UseStaticFiles
of UseDirectoryBrowser
. De volledige map en de bijbehorende submappen worden openbaar toegankelijk. Sla bestanden op die geschikt zijn voor het publiek in een toegewezen map, zoals <content_root>/wwwroot
. Scheid deze bestanden van MVC-weergaven, Razor Pagina's, configuratiebestanden, enzovoort.
De URL's voor inhoud die worden weergegeven met
UseDirectoryBrowser
,UseStaticFiles
enMapStaticAssets
zijn onderworpen aan de vertrouwelijkheids- en tekenbeperkingen van het onderliggende bestandssysteem. Windows is bijvoorbeeld niet hoofdlettergevoelig, maar macOS en Linux zijn dat niet.ASP.NET Core-apps die worden gehost in IIS, gebruiken de ASP.NET Core Module- om alle aanvragen door te sturen naar de app, inclusief statische bestandsaanvragen. De statische IIS-bestandshandler wordt niet gebruikt en heeft geen kans om aanvragen te verwerken.
Voer de volgende stappen uit in IIS-beheer om de statische IIS-bestandshandler op server- of websiteniveau te verwijderen:
- Navigeer naar de functie Modules.
- Selecteer StaticFileModule in de lijst.
- Klik op verwijderen in de zijbalk Acties.
Waarschuwing
Als de statische IIS-bestandshandler is ingeschakeld en de ASP.NET Core-module onjuist is geconfigureerd, worden statische bestanden geleverd. Dit gebeurt bijvoorbeeld als het web.config bestand niet is geïmplementeerd.
- Plaats codebestanden, inclusief
.cs
en.cshtml
, buiten de webhoofdmap van het app-project. Daarom wordt er een logische scheiding gemaakt tussen de inhoud aan de clientzijde van de app en servercode. Dit voorkomt dat code aan de serverzijde wordt gelekt.
Bestanden buiten wwwroot beschikbaar maken door IWebHostEnvironment.WebRootPath bij te werken.
Wanneer IWebHostEnvironment.WebRootPath is ingesteld op een andere map dan wwwroot
:
- In de ontwikkelomgeving worden statische assets in zowel
wwwroot
als de bijgewerkteIWebHostEnvironment.WebRootPath
geleverd vanuitwwwroot
. - In een andere omgeving dan ontwikkeling worden dubbele statische assets geleverd vanuit de bijgewerkte map
IWebHostEnvironment.WebRootPath
.
Overweeg een web-app die is gemaakt met de lege websjabloon:
Bevat een
Index.html
bestand inwwwroot
enwwwroot-custom
.Met het volgende bijgewerkte
Program.cs
-bestand waarmeeWebRootPath = "wwwroot-custom"
wordt ingesteld: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();
In de voorgaande code zijn aanvragen aan /
:
- In de ontwikkelomgeving wordt
wwwroot/Index.html
geretourneerd - In een andere omgeving dan de ontwikkeling retourneer
wwwroot-custom/Index.html
Gebruik een van de volgende methoden om ervoor te zorgen dat assets van wwwroot-custom
worden geretourneerd:
Dubbele benoemde assets verwijderen in
wwwroot
.Stel
"ASPNETCORE_ENVIRONMENT"
inProperties/launchSettings.json
in op een andere waarde dan"Development"
.Schakel statische webassets volledig uit door
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
in het projectbestand in te stellen. WAARSCHUWING, als u statische webassets uitschakelt, worden Razor klassebibliothekenuitgeschakeld.Voeg de volgende XML toe aan het projectbestand:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
Met de volgende code wordt IWebHostEnvironment.WebRootPath
bijgewerkt naar een niet-ontwikkelingswaarde, waardoor dubbele inhoud wordt geretourneerd vanuit wwwroot-custom
in plaats van 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();
Aanvullende informatiebronnen
Door Rick Anderson
Statische bestanden, zoals HTML, CSS, afbeeldingen en JavaScript, zijn assets die een ASP.NET Core-app standaard rechtstreeks aan clients dienen.
Statische bestanden verwerken
Statische bestanden worden opgeslagen in de webroot-directory van de projectmap . De standaardmap is {content root}/wwwroot
, maar kan worden gewijzigd met de methode UseWebRoot. Zie Hoofdmap van inhoud en webhoofdmapvoor meer informatie.
Met de methode CreateBuilder wordt de inhoudwortel ingesteld op de huidige map.
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();
Statische bestanden zijn toegankelijk via een pad relatief aan de webhoofdmap. De Web Application projectsjablonen bevatten bijvoorbeeld verschillende mappen in de map wwwroot
:
wwwroot
css
js
lib
Overweeg het maken van de wwwroot/images map en het toevoegen van het wwwroot/images/MyImage.jpg
bestand. De URI-indeling voor toegang tot een bestand in de map images
is https://<hostname>/images/<image_file_name>
. Bijvoorbeeld https://localhost:5001/images/MyImage.jpg
Bestanden serveren in de hoofdmap van het web
Met de standaardweb-app-sjablonen wordt de methode UseStaticFiles in Program.cs
aangeroepen, waarmee statische bestanden kunnen worden verwerkt:
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();
De parameterloze overbelasting van de UseStaticFiles
-methode markeert de bestanden in webhoofdmap als toegankelijk. De volgende markeringen verwijzen wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
In de voorgaande markup verwijst het tilde-teken ~
naar de webroot.
Bestanden buiten de hoofdmap van het web verwerken
Overweeg een directorystructuur waarin de statische bestanden die moeten worden geserveerd zich buiten de web-hoofdmap bevinden:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Een request kan toegang krijgen tot het red-rose.jpg
bestand door de Static File Middleware als volgt te configureren:
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();
In de voorgaande code wordt de MyStaticFiles directorystructuur publiek toegankelijk gemaakt via het StaticFiles URI-segment. Een verzoek aan https://<hostname>/StaticFiles/images/red-rose.jpg
bedient het red-rose.jpg
-bestand.
De volgende markeringen verwijzen MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Zie Bestanden vanaf meerdere locaties bedienenals u bestanden van meerdere locaties wilt gebruiken.
HTTP-antwoordheaders instellen
Een StaticFileOptions-object kan worden gebruikt om HTTP-antwoordheaders in te stellen. Naast het configureren van statische bestanden vanuit de webhoofdmap, stelt de volgende code de Cache-Control header in:
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();
De voorgaande code maakt statische bestanden openbaar beschikbaar in de lokale cache gedurende één week (604800 seconden).
Autorisatie van statische bestanden
De ASP.NET Core-sjablonen roepen UseStaticFiles aan voordat u UseAuthorizationaanroept. De meeste apps volgen dit patroon. Wanneer de Static File Middleware wordt aangeroepen vóór de autorisatie-middleware:
- Er worden geen autorisatiecontroles uitgevoerd op de statische bestanden.
- Statische bestanden die worden geleverd door de Static File Middleware, zoals die onder
wwwroot
, zijn openbaar toegankelijk.
Statische bestanden verwerken op basis van autorisatie:
- Sla ze buiten
wwwroot
op. -
UseStaticFiles
aanroepen, een pad opgeven na het aanroepen vanUseAuthorization
. - Stel het autorisatiebeleid voor terugval in.
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();
In de voorgaande code vereist het autorisatiebeleid voor terugval alle gebruikers moeten worden geverifieerd. Eindpunten zoals controllers, Razor pagina's, enzovoort, die hun eigen autorisatievereisten specificeren, maken geen gebruik van het standaard autorisatiebeleid. Zo gebruiken Razor pagina's, controllers of actiemethoden met [AllowAnonymous]
of [Authorize(PolicyName="MyPolicy")]
het toegepaste autorisatiekenmerk in plaats van het autorisatiebeleid voor terugval.
RequireAuthenticatedUser voegt DenyAnonymousAuthorizationRequirement toe aan het huidige exemplaar, waardoor de huidige gebruiker wordt geverifieerd.
Statische assets onder wwwroot
zijn openbaar toegankelijk omdat de standaard statische bestands-middleware (app.UseStaticFiles();
) wordt aangeroepen vóór UseAuthentication
. Voor statische assets in de map MyStaticFiles is verificatie vereist. De voorbeeldcode laat dit zien.
Een alternatieve benadering voor het verwerken van bestanden op basis van autorisatie is het volgende:
Bewaar ze buiten
wwwroot
en elke map die toegankelijk is voor de Static File Middleware.Serveer ze via een actiemethode waarop autorisatie wordt toegepast en retourneer een FileResult-object:
[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"); } }
Voor de voorgaande benadering is een pagina of eindpunt per bestand vereist. De volgende code retourneert bestanden of uploadt bestanden voor geverifieerde gebruikers:
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();
Zie de map StaticFileAuth GitHub voor het volledige voorbeeld.
Bladeren door mappen
Bladeren in mappen staat het weergeven van inhoud binnen opgegeven mappen toe.
Bladeren door mappen is standaard uitgeschakeld om veiligheidsredenen. Zie Beveiligingsoverwegingen voor statische bestandenvoor meer informatie.
Bladeren door mappen inschakelen met AddDirectoryBrowser en 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();
Met de voorgaande code kunt u bladeren door mappen van de wwwroot/images map met behulp van de URL https://<hostname>/MyImages
, met koppelingen naar elk bestand en elke map:
AddDirectoryBrowser
voegt services toe die vereist zijn voor de middleware voor het bladeren door mappen, waaronder HtmlEncoder. Deze services kunnen worden toegevoegd door andere aanroepen, zoals AddRazorPages, maar we raden u aan AddDirectoryBrowser
aan te roepen om ervoor te zorgen dat de services in alle apps worden toegevoegd.
Standaarddocumenten serveren
Het instellen van een standaardpagina biedt bezoekers een startpunt op een site. Als u een standaardbestand van wwwroot
wilt leveren zonder dat de aanvraag-URL de naam van het bestand moet opnemen, roept u de UseDefaultFiles methode aan:
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
moet worden aangeroepen voordat UseStaticFiles
het standaardbestand moet leveren.
UseDefaultFiles
is een URL-rewriter die het bestand niet dient.
Met UseDefaultFiles
worden verzoeken naar een map in wwwroot
doorzocht op:
default.htm
default.html
index.htm
index.html
Het eerste bestand uit de lijst wordt geleverd alsof de aanvraag de naam van het bestand bevat. De browser-URL blijft de aangevraagde URI weerspiegelen.
Met de volgende code wordt de standaardbestandsnaam gewijzigd in mydefault.html
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
UseFileServer voor standaarddocumenten
UseFileServer combineert de functionaliteit van UseStaticFiles
, UseDefaultFiles
en eventueel UseDirectoryBrowser
.
Roep app.UseFileServer
aan om het leveren van statische bestanden en het standaardbestand in te schakelen. Bladeren in mappen is niet ingeschakeld:
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();
Met de volgende code kunt u statische bestanden, het standaardbestand en bladeren door mappen uitvoeren:
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();
Overweeg de volgende maphiërarchie:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
Met de volgende code kunt u statische bestanden, het standaardbestand en het bladeren door mappen van MyStaticFiles
inschakelen:
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 moet worden aangeroepen wanneer de eigenschapswaarde van de EnableDirectoryBrowsing
is true
.
Met behulp van de voorgaande bestandshiërarchie en code worden URL's als volgt omgezet:
URI | Antwoord |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Als er geen standaardbestand met de naam bestaat in de map MyStaticFiles, retourneert https://<hostname>/StaticFiles
de mapvermelding met klikbare koppelingen:
UseDefaultFiles en UseDirectoryBrowser voeren een omleiding aan de clientzijde uit van de doel-URI zonder een afsluitende /
naar de doel-URI met een afsluitende /
. Bijvoorbeeld van https://<hostname>/StaticFiles
tot https://<hostname>/StaticFiles/
. Relatieve URL's in de StaticFiles map zijn ongeldig zonder een afsluitende slash (/
) tenzij de RedirectToAppendTrailingSlash optie van DefaultFilesOptions wordt gebruikt.
FileExtensionContentTypeProvider
De FileExtensionContentTypeProvider-klasse bevat een Mappings
eigenschap die fungeert als toewijzing van bestandsextensies aan MIME-inhoudstypen. In het volgende voorbeeld worden verschillende bestandsextensies toegewezen aan bekende MIME-typen. De .rtf-extensie wordt vervangen en .mp4 wordt verwijderd:
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();
Zie MIME-inhoudstypen.
Niet-standaardinhoudstypen
De Static File Middleware begrijpt bijna 400 bekende bestandsinhoudstypen. Als de gebruiker een bestand met een onbekend bestandstype aanvraagt, geeft de Static File Middleware de aanvraag door aan de volgende middleware in de pijplijn. Als er geen middleware de aanvraag verwerkt, wordt een 404 Niet gevonden antwoord geretourneerd. Als bladeren in mappen is ingeschakeld, wordt een koppeling naar het bestand weergegeven in een lijst met mappen.
Met de volgende code kunt u onbekende typen leveren en het onbekende bestand weergeven als een afbeelding:
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();
Met de voorgaande code wordt een aanvraag voor een bestand met een onbekend inhoudstype geretourneerd als een afbeelding.
Waarschuwing
Het inschakelen van ServeUnknownFileTypes is een beveiligingsrisico. Het is standaard uitgeschakeld en het gebruik ervan wordt afgeraden. FileExtensionContentTypeProvider biedt een veiliger alternatief voor bestanden met niet-standaardextensies.
Bestanden vanaf meerdere locaties leveren
Houd rekening met de volgende Razor pagina waarop het /MyStaticFiles/image3.png
-bestand wordt weergegeven:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
en UseFileServer
zijn standaard de bestandsprovider die naar wwwroot
verwijst. Extra exemplaren van UseStaticFiles
en UseFileServer
kunnen worden geleverd met andere bestandsproviders om bestanden van andere locaties te verwerken. In het volgende voorbeeld wordt UseStaticFiles
twee keer aanroepen om bestanden uit zowel wwwroot
als MyStaticFiles
te verwerken:
app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Gebruik de voorgaande code:
- Het
/MyStaticFiles/image3.png
-bestand wordt weergegeven. - De Image Tag HelpersAppendVersion worden niet toegepast omdat de Tag Helpers afhankelijk zijn van WebRootFileProvider.
WebRootFileProvider
is niet bijgewerkt om de mapMyStaticFiles
op te nemen.
Met de volgende code wordt de WebRootFileProvider
bijgewerkt, waardoor de Helper voor afbeeldingentags een versie kan opgeven:
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();
Notitie
De voorgaande benadering is van toepassing op Razor Pagina's en MVC-apps. Zie ASP.NET Core Blazor statische bestandenvoor richtlijnen die van toepassing zijn op Blazor Web Apps.
Beveiligingsoverwegingen voor statische bestanden
Waarschuwing
UseDirectoryBrowser
en UseStaticFiles
kunnen geheimen lekken. Het uitschakelen van mapnavigatie in productie wordt ten zeerste aanbevolen. Controleer zorgvuldig welke directories zijn ingeschakeld via UseStaticFiles
of UseDirectoryBrowser
. De volledige map en de bijbehorende submappen worden openbaar toegankelijk. Sla bestanden op die geschikt zijn voor het publiek in een toegewezen map, zoals <content_root>/wwwroot
. Scheid deze bestanden van MVC-weergaven, Razor Pagina's, configuratiebestanden, enzovoort.
De URL's voor inhoud die worden weergegeven met
UseDirectoryBrowser
enUseStaticFiles
zijn onderhevig aan de gevoeligheid van hoofdletters en tekens van het onderliggende bestandssysteem. Windows is bijvoorbeeld niet hoofdlettergevoelig, maar macOS en Linux zijn dat niet.ASP.NET Core-apps die worden gehost in IIS, gebruiken de ASP.NET Core Module- om alle aanvragen door te sturen naar de app, inclusief statische bestandsaanvragen. De statische IIS-bestandshandler wordt niet gebruikt en heeft geen kans om aanvragen te verwerken.
Voer de volgende stappen uit in IIS-beheer om de statische IIS-bestandshandler op server- of websiteniveau te verwijderen:
- Navigeer naar de functie Modules.
- Selecteer StaticFileModule in de lijst.
- Klik op verwijderen in de zijbalk Acties.
Waarschuwing
Als de statische IIS-bestandshandler is ingeschakeld en de ASP.NET Core-module onjuist is geconfigureerd, worden statische bestanden geleverd. Dit gebeurt bijvoorbeeld als het web.config bestand niet is geïmplementeerd.
- Plaats codebestanden, inclusief
.cs
en.cshtml
, buiten de webroot van het app-project. Daarom wordt er een logische scheiding gemaakt tussen de inhoud aan de clientzijde van de app en servercode. Dit voorkomt dat code aan de serverzijde wordt gelekt.
Bestanden buiten wwwroot aanbieden door IWebHostEnvironment.WebRootPath te updaten.
Wanneer IWebHostEnvironment.WebRootPath is ingesteld op een andere map dan wwwroot
:
- In de ontwikkelomgeving worden statische assets in zowel
wwwroot
als de bijgewerkteIWebHostEnvironment.WebRootPath
geleverd vanuitwwwroot
. - In een omgeving anders dan een ontwikkelomgeving worden gedupliceerde statische assets bediend vanuit de bijgewerkte map
IWebHostEnvironment.WebRootPath
.
Overweeg een web-app die is gemaakt met de lege websjabloon:
Bevat een
Index.html
bestand inwwwroot
enwwwroot-custom
.Met het volgende bijgewerkte
Program.cs
-bestand waarmeeWebRootPath = "wwwroot-custom"
wordt ingesteld: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();
In de voorgaande code worden verzoeken aan /
:
- In de ontwikkelomgeving wordt
wwwroot/Index.html
geretourneerd - In elke andere omgeving dan de ontwikkelomgeving, voer terug
wwwroot-custom/Index.html
Gebruik een van de volgende methoden om ervoor te zorgen dat assets van wwwroot-custom
worden geretourneerd:
Dubbele benoemde assets verwijderen in
wwwroot
.Stel
"ASPNETCORE_ENVIRONMENT"
inProperties/launchSettings.json
in op een andere waarde dan"Development"
.Schakel statische webassets volledig uit door
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
in het projectbestand in te stellen. WAARSCHUWING: als u statische webassets uitschakelt, worden de klassebibliotheken Razorook uitgeschakeld.Voeg de volgende JSON toe aan het projectbestand:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
Met de volgende code wordt IWebHostEnvironment.WebRootPath
bijgewerkt naar een niet-ontwikkelingswaarde, waardoor dubbele inhoud wordt geretourneerd vanuit wwwroot-custom
in plaats van 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();
Aanvullende informatiebronnen
Door Rick Anderson en Kirk Larkin
Statische bestanden, zoals HTML, CSS, afbeeldingen en JavaScript, zijn assets die een ASP.NET Core-app standaard rechtstreeks aan clients dienen.
Statische bestanden verwerken
Statische bestanden worden opgeslagen in de webhoofdmap van het project map. De standaardmap is {content root}/wwwroot
, maar kan worden gewijzigd met de methode UseWebRoot. Zie Inhoudshoofdmap en Webhoofdmapvoor meer informatie.
Met de methode CreateBuilder wordt de inhoudshoofdmap ingesteld op de huidige map:
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();
Statische bestanden zijn toegankelijk via een pad dat relatief is ten opzichte van de webroot. De Web Application projectsjablonen bevatten bijvoorbeeld verschillende mappen in de map wwwroot
:
wwwroot
css
js
lib
Overweeg het maken van de wwwroot/images map en het toevoegen van het wwwroot/images/MyImage.jpg
bestand. De URI-indeling voor toegang tot een bestand in de map images
is https://<hostname>/images/<image_file_name>
. Bijvoorbeeld https://localhost:5001/images/MyImage.jpg
Bestanden serveren in de hoofdmap van het web
Met de standaardweb-app-sjablonen wordt de methode UseStaticFiles in Program.cs
aangeroepen, waarmee statische bestanden kunnen worden verwerkt:
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();
De overbelasting van de UseStaticFiles
methode zonder parameters markeert de bestanden in webhoofdmap als serveerbaar. De volgende markeringen verwijzen wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
In de voorgaande markup verwijst het tilde-teken ~
naar de webroot.
Bestanden buiten de webroot aanbieden
Denk aan een directorystructuur waarin de statische bestanden die geleverd moeten worden zich buiten de webroot bevinden.
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Een verzoek kan toegang krijgen tot het red-rose.jpg
-bestand door de Static File Middleware als volgt te configureren:
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();
In de voorgaande code wordt de directorystructuur van MyStaticFiles via het StaticFiles URI-segment publiek toegankelijk gemaakt. Een aanvraag naar https://<hostname>/StaticFiles/images/red-rose.jpg
levert het red-rose.jpg
-bestand op.
De volgende markeringen verwijzen MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Zie Bestanden vanaf meerdere locaties bedienenals u bestanden van meerdere locaties wilt gebruiken.
HTTP-antwoordheaders instellen
Een StaticFileOptions-object kan worden gebruikt om HTTP-antwoordheaders in te stellen. Naast het configureren van statische bestanden vanuit de webhoofdmap, stelt de volgende code de Cache-Control header in:
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();
De voorgaande code maakt statische bestanden openbaar beschikbaar in de lokale cache gedurende één week (604800 seconden).
Autorisatie van statische bestanden
De ASP.NET Core-sjablonen roepen UseStaticFiles aan voordat u UseAuthorizationaanroept. De meeste apps volgen dit patroon. Wanneer de Static File Middleware wordt aangeroepen vóór de autorisatie-middleware:
- Er worden geen autorisatiecontroles uitgevoerd op de statische bestanden.
- Statische bestanden die worden geleverd door de Static File Middleware, zoals die onder
wwwroot
, zijn openbaar toegankelijk.
Statische bestanden verwerken op basis van autorisatie:
- Sla ze buiten
wwwroot
op. -
UseStaticFiles
aanroepen, een pad opgeven na het aanroepen vanUseAuthorization
. - Stel het terugvalautorisatiebeleid in.
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();
In de voorgaande code vereist het autorisatiebeleid voor terugval alle gebruikers moeten worden geverifieerd. Eindpunten zoals controllers, Razor Pagina's, enzovoort, die hun eigen autorisatievereisten specificeren, gebruiken niet het standaard autorisatiebeleid. Zo gebruiken Razor pagina's, controllers of actiemethoden met [AllowAnonymous]
of [Authorize(PolicyName="MyPolicy")]
het toegepaste autorisatiekenmerk in plaats van het autorisatiebeleid voor terugval.
RequireAuthenticatedUser voegt DenyAnonymousAuthorizationRequirement toe aan het huidige exemplaar, waardoor de huidige gebruiker wordt geverifieerd.
Statische assets onder wwwroot
zijn openbaar toegankelijk omdat de standaard statische bestands-middleware (app.UseStaticFiles();
) wordt aangeroepen vóór UseAuthentication
. Voor statische assets in de map MyStaticFiles is verificatie vereist. De voorbeeldcode laat dit zien.
Een alternatieve benadering voor het verwerken van bestanden op basis van autorisatie is het volgende:
- Bewaar ze buiten
wwwroot
en elke map die toegankelijk is voor de Static File Middleware. - Serveer ze via een actiemethode waarop autorisatie wordt toegepast en retourneer een FileResult-object:
[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");
}
}
Bladeren door mappen
Directory-browsing staat het tonen van maplijsten binnen specifieke mappen toe.
Bladeren door mappen is standaard uitgeschakeld om veiligheidsredenen. Zie Beveiligingsoverwegingen voor statische bestandenvoor meer informatie.
Bladeren door mappen inschakelen met AddDirectoryBrowser en 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();
Met de voorgaande code kunt u bladeren door mappen van de wwwroot/images map met behulp van de URL https://<hostname>/MyImages
, met koppelingen naar elk bestand en elke map:
AddDirectoryBrowser
voegt services toe die vereist zijn voor de middleware voor het bladeren door mappen, waaronder HtmlEncoder. Deze services kunnen worden toegevoegd door andere aanroepen, zoals AddRazorPages, maar we raden u aan AddDirectoryBrowser
aan te roepen om ervoor te zorgen dat de services in alle apps worden toegevoegd.
Standaarddocumenten beschikbaar maken
Het instellen van een standaardpagina biedt bezoekers een startpunt op een site. Als u een standaardbestand van wwwroot
wilt leveren zonder dat de aanvraag-URL de naam van het bestand moet opnemen, roept u de UseDefaultFiles methode aan:
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
moet worden aangeroepen voordat UseStaticFiles
het standaardbestand moet leveren.
UseDefaultFiles
is een URL-rewriter die het bestand niet dient.
Met UseDefaultFiles
kunnen aanvragen naar een map in wwwroot
worden doorzocht op:
default.htm
default.html
index.htm
index.html
Het eerste bestand uit de lijst wordt geleverd alsof de aanvraag de naam van het bestand bevat. De browser-URL blijft de aangevraagde URI weerspiegelen.
Met de volgende code wordt de standaardbestandsnaam gewijzigd in mydefault.html
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
UseFileServer voor standaarddocumenten
UseFileServer combineert de functionaliteit van UseStaticFiles
, UseDefaultFiles
en eventueel UseDirectoryBrowser
.
Roep app.UseFileServer
aan om het leveren van statische bestanden en het standaardbestand in te schakelen. Bladeren in mappen is niet ingeschakeld:
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();
Met de volgende code kunt u statische bestanden, het standaardbestand en bladeren door mappen uitvoeren:
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();
Houd rekening met de volgende mappenstructuur:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
Met de volgende code kunt u statische bestanden, het standaardbestand en het bladeren door mappen van MyStaticFiles
inschakelen:
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 moet worden aangeroepen wanneer de eigenschapswaarde van de EnableDirectoryBrowsing
is true
.
Met behulp van de voorgaande bestandshiërarchie en code worden URL's als volgt omgezet:
URI | Antwoord |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Als er geen standaardbestand met de naam bestaat in de map MyStaticFiles, retourneert https://<hostname>/StaticFiles
de mapvermelding met klikbare koppelingen:
UseDefaultFiles en UseDirectoryBrowser voeren een client-side omleiding uit van de doel-URI zonder aanhangende /
naar de doel-URI met een afsluitende /
. Bijvoorbeeld van https://<hostname>/StaticFiles
tot https://<hostname>/StaticFiles/
. Relatieve URL's in de StaticFiles map zijn ongeldig zonder een afsluitende slash (/
) tenzij de RedirectToAppendTrailingSlash optie van DefaultFilesOptions wordt gebruikt.
FileExtensionContentTypeProvider
De FileExtensionContentTypeProvider-klasse bevat een Mappings
eigenschap die fungeert als toewijzing van bestandsextensies aan MIME-inhoudstypen. In het volgende voorbeeld worden verschillende bestandsextensies toegewezen aan bekende MIME-typen. De .rtf-extensie wordt vervangen en .mp4 wordt verwijderd:
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();
Zie MIME-inhoudstypen.
Niet-standaardinhoudstypen
De Static File Middleware begrijpt bijna 400 bekende bestandsinhoudstypen. Als de gebruiker een bestand met een onbekend bestandstype aanvraagt, geeft de Static File Middleware de aanvraag door aan de volgende middleware in de pijplijn. Als er geen middleware de aanvraag verwerkt, wordt een 404 Niet gevonden antwoord geretourneerd. Als bladeren in mappen is ingeschakeld, wordt een koppeling naar het bestand weergegeven in een lijst met mappen.
Met de volgende code kunt u onbekende typen leveren en het onbekende bestand weergeven als een afbeelding:
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();
Met de voorgaande code wordt een aanvraag voor een bestand met een onbekend inhoudstype geretourneerd als een afbeelding.
Waarschuwing
Het inschakelen van ServeUnknownFileTypes is een beveiligingsrisico. Het is standaard uitgeschakeld en het gebruik ervan wordt afgeraden. FileExtensionContentTypeProvider biedt een veiliger alternatief voor bestanden met niet-standaardextensies.
Bestanden vanaf meerdere locaties leveren
Houd rekening met de volgende Razor pagina waarop het /MyStaticFiles/image3.png
-bestand wordt weergegeven:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
en UseFileServer
worden standaard ingesteld op de bestandsprovider die naar wwwroot
verwijst. Extra exemplaren van UseStaticFiles
en UseFileServer
kunnen worden geleverd met andere bestandsproviders om bestanden van andere locaties te verwerken. In het volgende voorbeeld wordt UseStaticFiles
twee keer aanroepen om bestanden uit zowel wwwroot
als MyStaticFiles
te verwerken:
app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Gebruik de voorgaande code:
- Het
/MyStaticFiles/image3.png
-bestand wordt weergegeven. - De afbeeldings-taghelpersAppendVersion wordt niet toegepast omdat de taghelpers afhankelijk zijn van WebRootFileProvider.
WebRootFileProvider
is niet bijgewerkt om de mapMyStaticFiles
op te nemen.
Met de volgende code wordt de WebRootFileProvider
bijgewerkt, waardoor de Helper voor afbeeldingentags een versie kan opgeven:
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();
Beveiligingsoverwegingen voor statische bestanden
Waarschuwing
UseDirectoryBrowser
en UseStaticFiles
kunnen geheimen lekken. Het uitschakelen van directory browsing in productie wordt ten zeerste aanbevolen. Controleer zorgvuldig welke directories zijn ingeschakeld via UseStaticFiles
of UseDirectoryBrowser
. De volledige map en de bijbehorende submappen worden openbaar toegankelijk. Sla bestanden op die geschikt zijn voor het publiek in een toegewezen map, zoals <content_root>/wwwroot
. Scheid deze bestanden van MVC-weergaven, Razor Pagina's, configuratiebestanden, enzovoort.
De URL's voor inhoud die worden weergegeven met
UseDirectoryBrowser
enUseStaticFiles
zijn onderhevig aan de gevoeligheid van hoofdletters en tekens van het onderliggende bestandssysteem. Windows is bijvoorbeeld niet hoofdlettergevoelig, maar macOS en Linux zijn dat niet.ASP.NET Core-apps die worden gehost in IIS, gebruiken de ASP.NET Core Module- om alle aanvragen door te sturen naar de app, inclusief statische bestandsaanvragen. De statische IIS-bestandshandler wordt niet gebruikt en heeft geen kans om aanvragen te verwerken.
Voer de volgende stappen uit in IIS-beheer om de statische IIS-bestandshandler op server- of websiteniveau te verwijderen:
- Navigeer naar de functie Modules.
- Selecteer StaticFileModule in de lijst.
- Klik op verwijderen in de zijbalk Acties.
Waarschuwing
Als de statische IIS-bestandshandler is ingeschakeld en de ASP.NET Core-module onjuist is geconfigureerd, worden statische bestanden geleverd. Dit gebeurt bijvoorbeeld als het web.config bestand niet is geïmplementeerd.
- Plaats codebestanden, inclusief
.cs
en.cshtml
, buiten de webroot van het app-project . Daarom wordt er een logische scheiding gemaakt tussen de inhoud aan de clientzijde van de app en servercode. Dit voorkomt dat code aan de serverzijde wordt gelekt.
Bestanden buiten wwwroot serveren door IWebHostEnvironment.WebRootPath bij te werken
Wanneer IWebHostEnvironment.WebRootPath is ingesteld op een andere map dan wwwroot
:
- In de ontwikkelomgeving worden statische assets in zowel
wwwroot
als de bijgewerkteIWebHostEnvironment.WebRootPath
geleverd vanuitwwwroot
. - In een andere omgeving dan ontwikkeling worden dubbele statische assets geleverd vanuit de bijgewerkte map
IWebHostEnvironment.WebRootPath
.
Overweeg een web-app die is gemaakt met de lege websjabloon:
Bevat een
Index.html
bestand inwwwroot
enwwwroot-custom
.Met het volgende bijgewerkte
Program.cs
-bestand waarmeeWebRootPath = "wwwroot-custom"
wordt ingesteld: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();
In de voorgaande code worden verzoeken aan /
:
- In de ontwikkelomgeving wordt
wwwroot/Index.html
geretourneerd - In een andere omgeving dan de ontwikkelomgeving, retourneer
wwwroot-custom/Index.html
Gebruik een van de volgende methoden om ervoor te zorgen dat assets van wwwroot-custom
worden geretourneerd:
Dubbele benoemde assets verwijderen in
wwwroot
.Stel
"ASPNETCORE_ENVIRONMENT"
inProperties/launchSettings.json
in op een andere waarde dan"Development"
.Schakel statische webassets volledig uit door
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
in het projectbestand in te stellen. WAARSCHUWING, als u statische webassets uitschakelt, worden Razor bibliotheken van klassenook uitgeschakeld.Voeg de volgende JSON toe aan het projectbestand:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
Met de volgende code wordt IWebHostEnvironment.WebRootPath
bijgewerkt naar een niet-ontwikkelingswaarde, waardoor dubbele inhoud wordt geretourneerd vanuit wwwroot-custom
in plaats van 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();
Aanvullende informatiebronnen
Door Rick Anderson en Kirk Larkin
Statische bestanden, zoals HTML, CSS, afbeeldingen en JavaScript, zijn assets die een ASP.NET Core-app standaard rechtstreeks aan clients dienen.
voorbeeldcode weergeven of downloaden (hoe te downloaden)
Statische bestanden verwerken
Statische bestanden worden opgeslagen in de webrootmap van de projectdirectory. De standaardmap is {content root}/wwwroot
, maar kan worden gewijzigd met de methode UseWebRoot. Zie voor meer informatie Inhoudshoofdmap en Webhoofdmap.
Met de methode CreateDefaultBuilder wordt de hoofdmap van de inhoud ingesteld op de huidige map:
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>();
});
}
De voorgaande code is gemaakt met de web-app-sjabloon.
Statische bestanden zijn toegankelijk via een pad ten opzichte van de webroot. De Web Application projectsjablonen bevatten bijvoorbeeld verschillende mappen in de map wwwroot
:
wwwroot
css
js
lib
Overweeg het maken van de wwwroot/images map en het toevoegen van het wwwroot/images/MyImage.jpg
bestand. De URI-indeling voor toegang tot een bestand in de map images
is https://<hostname>/images/<image_file_name>
. Bijvoorbeeld https://localhost:5001/images/MyImage.jpg
Bestanden serveren in de hoofdmap van het web
Met de standaardweb-app-sjablonen wordt de methode UseStaticFiles in Startup.Configure
aangeroepen, waarmee statische bestanden kunnen worden verwerkt:
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();
});
}
De parameterloze overbelasting van de UseStaticFiles
-methode markeert de bestanden in de webroot van als beschikbaar voor bediening. De volgende markeringen verwijzen wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
In de voorgaande code verwijst het tilde-teken ~/
naar de webhoofdmap.
Bestanden buiten de hoofdmap van het web verwerken
Denk aan een directory hiërarchie waarin de statische bestanden die moeten worden bediend zich buiten de webroot bevinden.
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Een aanvraag kan toegang krijgen tot het red-rose.jpg
bestand door de Static File Middleware als volgt te configureren:
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();
});
}
In de voorgaande code wordt de MyStaticFiles map hiërarchie openbaar toegankelijk gemaakt via het StaticFiles URI-segment. Een verzoek aan https://<hostname>/StaticFiles/images/red-rose.jpg
bedient het red-rose.jpg
-bestand.
De volgende markeringen verwijzen MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
HTTP-antwoordheaders instellen
Een StaticFileOptions-object kan worden gebruikt om HTTP-antwoordheaders in te stellen. Naast het configureren van het serveren van statische bestanden vanuit de webhoofdmap , stelt de volgende code de Cache-Control
-header in.
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();
});
}
Met de voorgaande code wordt de maximale leeftijd ingesteld op 604800 seconden (7 dagen).
Autorisatie van statische bestanden
De ASP.NET Core-sjablonen roepen UseStaticFiles aan voordat u UseAuthorizationaanroept. De meeste apps volgen dit patroon. Wanneer de Static File Middleware wordt aangeroepen vóór de autorisatie-middleware:
- Er worden geen autorisatiecontroles uitgevoerd op de statische bestanden.
- Statische bestanden die worden geleverd door de Static File Middleware, zoals die onder
wwwroot
, zijn openbaar toegankelijk.
Statische bestanden verwerken op basis van autorisatie:
- Sla ze buiten
wwwroot
op. -
UseStaticFiles
aanroepen, een pad opgeven na het aanroepen vanUseAuthorization
. - Stel het autorisatiebeleid voor terugval in.
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.
In de voorgaande code vereist het autorisatiebeleid voor terugval alle gebruikers moeten worden geverifieerd. Eindpunten zoals controllers en Razor Pagina's die hun eigen autorisatievereisten opgeven, maken geen gebruik van het reserveautorisatiebeleid. Zo gebruiken Razor pagina's, controllers of actiemethoden met [AllowAnonymous]
of [Authorize(PolicyName="MyPolicy")]
het toegepaste autorisatiekenmerk in plaats van het autorisatiebeleid voor terugval.
RequireAuthenticatedUser voegt DenyAnonymousAuthorizationRequirement toe aan het huidige exemplaar, waardoor de huidige gebruiker wordt geverifieerd.
Statische assets onder wwwroot
zijn openbaar toegankelijk omdat de standaard statische bestands-middleware (app.UseStaticFiles();
) wordt aangeroepen vóór UseAuthentication
. Voor statische assets in de map MyStaticFiles is verificatie vereist. De voorbeeldcode laat dit zien.
Een alternatieve benadering voor het verwerken van bestanden op basis van autorisatie is het volgende:
- Bewaar ze buiten
wwwroot
en elke map die toegankelijk is voor de Static File Middleware. - Serveer ze via een actiemethode waarop autorisatie wordt toegepast en retourneer een FileResult-object:
[Authorize]
public IActionResult BannerImage()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
Bladeren door mappen
Directory bladeren staat het tonen van mappenoverzichten binnen opgegeven mappen toe.
Bladeren door mappen is standaard uitgeschakeld om veiligheidsredenen. Zie Beveiligingsoverwegingen voor statische bestandenvoor meer informatie.
Bladeren door mappen inschakelen met:
-
AddDirectoryBrowser in
Startup.ConfigureServices
. -
UseDirectoryBrowser in
Startup.Configure
.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDirectoryBrowser();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// using Microsoft.Extensions.FileProviders;
// using System.IO;
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Met de voorgaande code kunt u bladeren door mappen van de wwwroot/images map met behulp van de URL https://<hostname>/MyImages
, met koppelingen naar elk bestand en elke map:
Standaarddocumenten aanbieden
Het instellen van een standaardpagina biedt bezoekers een startpunt op een site. Als u een standaardbestand van wwwroot
wilt leveren zonder dat de aanvraag-URL de naam van het bestand moet opnemen, roept u de UseDefaultFiles methode aan:
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
moet worden aangeroepen voordat UseStaticFiles
het standaardbestand moet leveren.
UseDefaultFiles
is een URL-rewriter die het bestand niet dient.
Met UseDefaultFiles
worden verzoeken naar een map in wwwroot
doorzocht op:
default.htm
default.html
index.htm
index.html
Het eerste bestand uit de lijst wordt geleverd alsof de aanvraag de naam van het bestand bevat. De browser-URL blijft de aangevraagde URI weerspiegelen.
Met de volgende code wordt de standaardbestandsnaam gewijzigd in mydefault.html
:
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
De volgende code toont Startup.Configure
met de voorgaande code:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
UseFileServer voor standaarddocumenten
UseFileServer combineert de functionaliteit van UseStaticFiles
, UseDefaultFiles
en eventueel UseDirectoryBrowser
.
Roep app.UseFileServer
aan om het leveren van statische bestanden en het standaardbestand in te schakelen. Bladeren in mappen is niet ingeschakeld. De volgende code toont Startup.Configure
met 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();
});
}
Met de volgende code kunt u statische bestanden, het standaardbestand en bladeren door mappen uitvoeren:
app.UseFileServer(enableDirectoryBrowsing: true);
De volgende code toont Startup.Configure
met de voorgaande code:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer(enableDirectoryBrowsing: true);
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
De volgende mapstructuur:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
Met de volgende code kunt u statische bestanden, het standaardbestand en het bladeren door mappen van MyStaticFiles
inschakelen:
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 moet worden aangeroepen wanneer de eigenschapswaarde van de EnableDirectoryBrowsing
is true
.
Met behulp van de bestandshiërarchie en voorgaande code worden URL's als volgt omgezet:
URI | Antwoord |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Als er geen standaardbestand met de naam bestaat in de map MyStaticFiles, retourneert https://<hostname>/StaticFiles
de mapvermelding met klikbare koppelingen:
UseDefaultFiles en UseDirectoryBrowser een omleiding aan de clientzijde uitvoeren vanaf de doel-URI zonder een volg-/
naar de doel-URI met een afsluitende /
. Bijvoorbeeld van https://<hostname>/StaticFiles
tot https://<hostname>/StaticFiles/
. Relatieve URL's in de StaticFiles map zijn ongeldig zonder een afsluitende slash (/
).
FileExtensionContentTypeProvider
De FileExtensionContentTypeProvider-klasse bevat een Mappings
eigenschap die fungeert als toewijzing van bestandsextensies aan MIME-inhoudstypen. In het volgende voorbeeld worden verschillende bestandsextensies toegewezen aan bekende MIME-typen. De .rtf-extensie wordt vervangen en .mp4 wordt verwijderd:
// 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"
});
De volgende code toont Startup.Configure
met de voorgaande code:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// using Microsoft.AspNetCore.StaticFiles;
// using Microsoft.Extensions.FileProviders;
// using System.IO;
// Set up custom content types - associating file extension to MIME type
var provider = new FileExtensionContentTypeProvider();
// Add new mappings
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";
// Replace an existing mapping
provider.Mappings[".rtf"] = "application/x-msdownload";
// Remove MP4 videos.
provider.Mappings.Remove(".mp4");
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages",
ContentTypeProvider = provider
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Zie MIME-inhoudstypen.
Niet-standaardinhoudstypen
De Static File Middleware begrijpt bijna 400 bekende bestandsinhoudstypen. Als de gebruiker een bestand met een onbekend bestandstype aanvraagt, geeft de Static File Middleware de aanvraag door aan de volgende middleware in de pijplijn. Als er geen middleware de aanvraag verwerkt, wordt een 404 Niet gevonden antwoord geretourneerd. Als bladeren in mappen is ingeschakeld, wordt een koppeling naar het bestand weergegeven in een lijst met mappen.
Met de volgende code kunt u onbekende typen leveren en het onbekende bestand weergeven als een afbeelding:
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
De volgende code toont Startup.Configure
met de voorgaande code:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Met de voorgaande code wordt een aanvraag voor een bestand met een onbekend inhoudstype geretourneerd als een afbeelding.
Waarschuwing
Het inschakelen van ServeUnknownFileTypes is een beveiligingsrisico. Het is standaard uitgeschakeld en het gebruik ervan wordt afgeraden. FileExtensionContentTypeProvider biedt een veiliger alternatief voor bestanden met niet-standaardextensies.
Bestanden vanaf meerdere locaties leveren
UseStaticFiles
en UseFileServer
staan standaard ingesteld op de bestandsprovider die naar wwwroot
verwijst. Extra exemplaren van UseStaticFiles
en UseFileServer
kunnen worden geleverd met andere bestandsproviders om bestanden van andere locaties te verwerken. Zie dit GitHub-probleemvoor meer informatie.
Beveiligingsoverwegingen voor statische bestanden
Waarschuwing
UseDirectoryBrowser
en UseStaticFiles
kunnen geheimen lekken. Het uitschakelen van bladeren door mappen in productie wordt ten zeerste aanbevolen. Controleer zorgvuldig welke mappen zijn geactiveerd via UseStaticFiles
of UseDirectoryBrowser
. De volledige map en de bijbehorende submappen worden openbaar toegankelijk. Sla bestanden op die geschikt zijn voor het publiek in een toegewezen map, zoals <content_root>/wwwroot
. Scheid deze bestanden van MVC-weergaven, Razor Pagina's, configuratiebestanden, enzovoort.
De URL's voor inhoud die worden weergegeven met
UseDirectoryBrowser
enUseStaticFiles
zijn onderhevig aan de gevoeligheid van hoofdletters en tekens van het onderliggende bestandssysteem. Windows is bijvoorbeeld niet hoofdlettergevoelig, maar macOS en Linux zijn dat niet.ASP.NET Core-apps die worden gehost in IIS, gebruiken de ASP.NET Core Module- om alle aanvragen door te sturen naar de app, inclusief statische bestandsaanvragen. De statische IIS-bestandshandler wordt niet gebruikt en heeft geen kans om aanvragen te verwerken.
Voer de volgende stappen uit in IIS-beheer om de statische IIS-bestandshandler op server- of websiteniveau te verwijderen:
- Navigeer naar de functie Modules.
- Selecteer StaticFileModule in de lijst.
- Klik op verwijderen in de zijbalk Acties.
Waarschuwing
Als de statische IIS-bestandshandler is ingeschakeld en de ASP.NET Core-module onjuist is geconfigureerd, worden statische bestanden geleverd. Dit gebeurt bijvoorbeeld als het web.config bestand niet is geïmplementeerd.
- Plaats codebestanden, inclusief
.cs
en.cshtml
, buiten de webhoofdmap van het app-project. Daarom wordt er een logische scheiding gemaakt tussen de inhoud aan de clientzijde van de app en servercode. Dit voorkomt dat code aan de serverzijde wordt gelekt.