Statiska filer i ASP.NET Core

Note

Det här är inte den senaste versionen av den här artikeln. Den aktuella versionen finns i .NET 10-versionen av den här artikeln.

Warning

Den här versionen av ASP.NET Core stöds inte längre. Mer information finns i .NET och .NET Core Support Policy. Den aktuella versionen finns i .NET 10-versionen av den här artikeln.

Statiska filer, även kallade statiska tillgångar, är filer i en ASP.NET Core app som inte genereras dynamiskt. I stället levererar appen dem direkt till klienterna på begäran. Exempel på statiska filer är HTML-, CSS-, bild- och JavaScript-filer.

Vägledning för Blazor statiska filer, som lägger till eller ersätter vägledningen i den här artikeln, finns i ASP.NET Core Blazor statiska filer.

Om du vill aktivera hantering av statiska filer i ASP.NET Core anropar du MapStaticAssets.

Som standard lagrar du statiska filer i projektets webbrotkatalog . Standardkatalogen är {CONTENT ROOT}/wwwroot, där {CONTENT ROOT} platshållaren är appens innehållsrot. Det är bara filer i wwwroot mappen som kan adresseras, så du behöver inte bekymra dig om resten av koden.

Endast filer med specifika filnamnstillägg som mappas till medietyper som stöds behandlas som statiska webbtillgångar.

Statiska webbtillgångar identifieras under byggfasen och optimeras med innehållsbaserad fingeravtrycksteknik för att förhindra återanvändning av gamla filer. Tillgångar komprimeras också för att minska tiden för tillgångsleverans.

Under körning exponeras de identifierade statiska webbtillgångarna som slutpunkter med HTTP-huvuden, såsom cachelagringshuvuden och huvuden för innehållstyp. En tillgång hanteras en gång tills filen ändras eller webbläsaren rensar cacheminnet. Rubrikerna ETag, Last-Modifiedoch Content-Type anges. Webbläsaren hindras från att använda inaktuella tillgångar när en app har uppdaterats.

Leverans av statiska tillgångar baseras på slutpunktsroutning, så det fungerar med andra slutpunktsmedvetna funktioner, till exempel auktorisering. Den är utformad för att fungera med alla användargränssnittsramverk, inklusive Blazor, Razor Pages och MVC.

Map Static Assets ger följande fördelar:

  • Komprimering under kompileringstiden för alla resurser i appen, inklusive JavaScript (JS) och formatmallar, men exklusive bild- och teckensnittsresurser som redan är komprimerade. Gzip-komprimering (Content-Encoding: gz) används under utveckling. Gzip- och Brotli-komprimering (Content-Encoding: br) används båda under publiceringen.
  • Fingeravtryckning för alla resurser vid byggtidpunkt med en Base64-kodad sträng av SHA-256-hashen för varje fils innehåll. Detta förhindrar återanvändning av en gammal version av en fil, även om den gamla filen cachelagras. Tillgångar med fingeravtryck cachelagras med immutable-direktivet, vilket resulterar i att webbläsaren aldrig begär resursen igen förrän den ändras. För webbläsare som inte stöder immutable direktivet läggs ett max-age direktiv till.
    • Även om en resurs inte är fingeravtrycksmarkerad genereras innehållsbaserade ETags för varje statisk resurs med filens fingeravtryckshash som ETag värde. Detta säkerställer att webbläsaren endast laddar ned en fil om dess innehåll ändras (eller om filen laddas ned för första gången).
    • Internt mappar ramverket fysiska tillgångar till deras fingeravtryck, vilket gör att appen kan:
      • Hitta automatiskt genererade resurser, till exempel Razor komponentbegränsad CSS för Blazors CSS-isoleringsfunktion och JS resurser som beskrivs av JS importkartor.
      • Generera länktaggar i <head> innehållet på sidan för att förinläsa resurser.

Map Static Assets tillhandahåller inte funktioner för minifiering eller andra filtransformeringar. Minifiering hanteras vanligtvis av anpassad kod eller verktyg från tredje part.

Note

MapStaticAssets serverar inte standarddokument av sig självt. Om du vill betjäna standarddokument anropar du först UseDefaultFiles och sedan UseStaticFiles. Mer information finns i avsnittet Hantera standarddokument .

Om du vill aktivera hantering av statiska filer i ASP.NET Core anropar du UseStaticFiles.

Som standard lagrar du statiska filer i projektets webbrotkatalog . Standardkatalogen är {CONTENT ROOT}/wwwroot, där {CONTENT ROOT} platshållaren är appens innehållsrot. Det är bara filer i wwwroot mappen som kan adresseras, så du behöver inte bekymra dig om resten av koden.

Vid körning returneras statiska webbresurser av mellanprogrammet för statiska filer när de begärs med huvuden för resursändring och Content-Type tillämpade. Rubrikerna ETag, Last-Modifiedoch Content-Type anges.

Mellanprogram för statiska filer möjliggör servering av statiska filer och används av appen när UseStaticFiles anropas i appens begärandepipeline. Filer levereras från sökvägen som anges i IWebHostEnvironment.WebRootPath eller WebRootFileProvider, vilket som standard är webbrotmappen, vanligtvis wwwroot.

Du kan också hantera statiska webbtillgångar från refererade projekt och paket.

Ändra webbrotkatalogen

Om du vill ändra webbroten använder du UseWebRoot -metoden. Mer information finns i översikten över grunderna i ASP.NET Core.

Förhindra publicering av filer i wwwroot med hjälp <Content> av projektobjektet i projektfilen. I följande exempel förhindras publicering av innehåll i wwwroot/local och dess underkataloger:

<ItemGroup>
  <Content Update="wwwroot\local\**\*.*" CopyToPublishDirectory="Never" />
</ItemGroup>

Metoden CreateBuilder anger innehållsroten till den aktuella katalogen:

var builder = WebApplication.CreateBuilder(args);

Metoden CreateDefaultBuilder anger innehållsroten till den aktuella katalogen:

Host.CreateDefaultBuilder(args)

I pipelinen för bearbetning av begäranden anropar UseHttpsRedirection du efter anropet till MapStaticAssetsför att aktivera servering av statiska filer från appens webbrot:

app.MapStaticAssets();

I pipelinen för bearbetning av begäranden anropar UseHttpsRedirection du efter anropet till UseStaticFilesför att aktivera servering av statiska filer från appens webbrot:

app.UseStaticFiles();

Statiska filer är tillgängliga via en sökväg i förhållande till webrooten.

Så här kommer du åt en avbildning på wwwroot/images/favicon.png:

  • URL-format: https://{HOST}/images/{FILE NAME}
    • Platshållaren {HOST} är värden.
    • Platshållaren {FILE NAME} är filnamnet.
  • Exempel
    • Absolut URL: https://localhost:5001/images/favicon.png
    • Rootrelativ URL: images/favicon.png

I en Blazor app images/favicon.png läser du in ikonbilden (favicon.png) från appens wwwroot/images mapp:

<link rel="icon" type="image/png" href="images/favicon.png" />

I Razor Pages- och MVC-appar pekar tilde-tecknet ~ på webbroten. I följande exempel ~/images/favicon.png läser du in ikonbilden (favicon.png) från appens wwwroot/images mapp:

<link rel="icon" type="image/png" href="~/images/favicon.png" />

Kortslut pipelinen för mellanprogram

För att undvika att köra hela mellanprogramvarupipelinen efter att en statisk tillgång har matchats, vilket är beteendet hos UseStaticFiles, anropar du ShortCircuitMapStaticAssets. Anropet ShortCircuit kör omedelbart slutpunkten och returnerar svaret, vilket förhindrar att andra mellanprogram körs för begäranden om statiska tillgångar:

app.MapStaticAssets().ShortCircuit();

Kontrollera cachelagring av statiska filer under utveckling

När du kör i Development-miljön, till exempel under Hot Reload i Visual Studio, åsidosätter ramverket cachehuvuden för att förhindra att webbläsare cachelagrar statiska filer. Det här beteendet hjälper till att säkerställa att den senaste versionen av filer används när filer ändras, vilket undviker problem med inaktuellt innehåll. I produktion ställer ramverket in rätt cache-rubriker så att webbläsare kan cachelagra statiska resurser som förväntat.

Om du vill inaktivera det här beteendet anger du EnableStaticAssetsDevelopmentCaching till true i Development miljöns appinställningsfil (appsettings.Development.json).

Statiska filer i icke-Development miljöer

När du kör en app lokalt är Development-miljön den enda miljön som aktiverar statiska webbresurser. Om du vill aktivera statiska filer för andra miljöer än Development under lokal utveckling och testning (till exempel i Staging miljön) anropar du UseStaticWebAssetsWebApplicationBuilder .

Warning

Anropa UseStaticWebAssets den exakta miljön för att förhindra aktivering av funktionen i produktion, eftersom den hanterar filer från separata platser på en annan disk än från projektet. Exemplet i det här avsnittet kontrollerar Staging för miljön med IsStaging.

if (builder.Environment.IsStaging())
{
    builder.WebHost.UseStaticWebAssets();
}

Hantera filer utanför webbrotkatalogen via IWebHostEnvironment.WebRootPath

När du anger IWebHostEnvironment.WebRootPath till en annan mapp än wwwroot, uppvisar appen följande standardbeteenden:

  • Development I miljön hanteras statiska tillgångar från wwwroot om tillgångar med samma namn finns i båda wwwroot och en annan mapp tilldelad till WebRootPath.
  • I alla andra miljöer än Development hanteras dubbletter av statiska resurser från WebRootPath mapp.

Överväg att skapa en webbapp från den tomma webbmallen:

  • Innehåller en fil Index.html i wwwroot och wwwroot-custom.
  • Filen Program har uppdaterats för att ange WebRootPath = "wwwroot-custom".
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    WebRootPath = "wwwroot-custom"
});

Som standard för begäranden till /:

  • I miljön Developmentwwwroot/Index.html returneras.
  • I alla andra miljöer än Developmentwwwroot-custom/Index.html returneras .

Använd wwwroot-custom av följande metoder för att säkerställa att tillgångar från alltid returneras:

  • Ta bort duplicerade namngivna tillgångar i wwwroot.

  • Ange ASPNETCORE_ENVIRONMENT i Properties/launchSettings.json till vilket värde som helst utom Development.

  • Inaktivera statiska webbtillgångar genom att ställa in <StaticWebAssetsEnabled> till false i appens projektfil. VARNING: Om du inaktiverar statiska webbtillgångar inaktiveras Razor klassbibliotek.

  • Lägg till följande XML i projektfilen:

    <ItemGroup>
      <Content Remove="wwwroot\**" />
    </ItemGroup>
    

Följande kod uppdaterar WebRootPath till ett värde som inte är ett utvecklingsvärde (Staging), vilket säkerställer att duplicerat innehåll returneras från wwwroot-custom istället för från wwwroot.

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    EnvironmentName = Environments.Staging,
    WebRootPath = "wwwroot-custom"
});

Mellanprogram för statisk fil

Mellanprogram för statiska filer möjliggör distribution av statiska filer i vissa scenarier för statiska filer, vanligtvis som ett komplement till slutpunktsroutningskonventionerna för Map Static Assets (MapStaticAssets).

Mellanprogramvara för statiska filer inkluderas i begärandebearbetningen när UseStaticFiles anropas i appens pipeline för begärandebearbetning, vanligtvis efter att slutpunktskonventionerna för Map Static Assets (MapStaticAssets) har lagts till.

Map Static Assets-slutpunktskonventioner används i appar som riktar sig mot .NET 9 eller senare. Mellanprogram för statiska filer måste användas i appar som har målversioner av .NET före .NET 9.

Mellanprogram för statiska filer serverar statiska filer, men det erbjuder inte samma optimeringsnivå som slutpunktskonventionerna för Map Static Assets. Funktionerna för komprimering vid byggtid och fingerprinting i slutpunktskonventionerna för Map Static Assets är inte tillgängliga om man enbart förlitar sig på mellanprogram för statiska filer.

Slutpunktkonventionerna är optimerade för att leverera resurser som appen har kännedom om vid körningstid. Om appen levererar filer från andra platser, till exempel från disken eller inbäddade resurser, använder du middleware för statiska filer.

Följande funktioner som tas upp i den här artikeln stöds med mellanprogram för statiska filer men inte med slutpunktskonventionerna för Map Static Assets:

Hantera filer utanför webbrotkatalogen via UseStaticFiles

Överväg följande kataloghierarki med statiska filer som finns utanför appens webbrot i en mapp med namnet ExtraStaticFiles:

  • wwwroot
    • css
    • images
    • js
  • ExtraStaticFiles
    • images
      • red-rose.jpg

En begäran kan få åtkomst till red-rose.jpg genom att konfigurera en ny instans av middleware för statiska filer:

Namnområden för följande API:

using Microsoft.Extensions.FileProviders;

I pipelinen för bearbetning av begäranden efter det befintliga anropet till antingen MapStaticAssets (.NET 9 eller senare) eller UseStaticFiles (.NET 8 eller tidigare):

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles")),
    RequestPath = "/static-files"
});

I föregående kod ExtraStaticFiles exponeras kataloghierarkin offentligt via static-files URL-segmentet. En begäran till https://{HOST}/StaticFiles/images/red-rose.jpg, där {HOST} platshållaren är värden, hanterar red-rose.jpg filen.

Följande markering refererar till ExtraStaticFiles/images/red-rose.jpg:

<img src="static-files/images/red-rose.jpg" alt="A red rose" />

I föregående exempel stöds tilde-slash-notation i Razor Sid- och MVC-vyer (src="~/StaticFiles/images/red-rose.jpg"), inte för Razor komponenter i Blazor appar.

Hantera filer från flera platser

Vägledningen i det här avsnittet gäller för Razor Pages- och MVC-appar. Vägledning som gäller för Blazor Web Apps finns i ASP.NET Core Blazor statiska filer.

Överväg följande markering som visar en företagslogotyp:

<img src="~/logo.png" asp-append-version="true" alt="Company logo">

Utvecklaren har för avsikt att använda hjälpverktyget för bildtaggen för att lägga till en version och hantera filen från en anpassad plats, en mapp med namnet ExtraStaticFiles.

I följande exempel anropas MapStaticAssets för att hantera filer från wwwroot och UseStaticFiles för att hantera filer från ExtraStaticFiles:

I pipelinen för bearbetning av begäranden efter det befintliga anropet till antingen MapStaticAssets (.NET 9 eller senare) eller UseStaticFiles (.NET 8 eller tidigare):

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles"))
});

I följande exempel anropas UseStaticFiles två gånger för att hantera filer från både wwwroot och ExtraStaticFiles.

I pipelinen för bearbetning av begäranden efter det befintliga anropet till UseStaticFiles:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles"))
});

Med hjälp av föregående kod ExtraStaticFiles/logo.png visas filen. Hjälpen för bildtaggen (AppendVersion) tillämpas dock inte eftersom Tag Helper är beroende av WebRootFileProvider, som inte har uppdaterats för att inkludera mappen ExtraStaticFiles.

Följande kod uppdaterar WebRootFileProvider för att inkludera ExtraStaticFiles mappen med hjälp av en CompositeFileProvider. På så sätt kan hjälpverktyget för bildtaggen tillämpa en version på ExtraStaticFiles bilder i mappen.

Namnområde för följande API:

using Microsoft.Extensions.FileProviders;

I pipelinen för bearbetning av begäran före det befintliga anropet till MapStaticAssets (.NET 9 eller senare) eller UseStaticFiles (.NET 8 eller tidigare):

var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
    Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles"));

var compositeProvider = new CompositeFileProvider(webRootProvider, newPathProvider);

app.Environment.WebRootFileProvider = compositeProvider;

UseStaticFiles och UseFileServer är som standard inställda på att filprovidern pekar på wwwroot. Ytterligare instanser av UseStaticFiles och UseFileServer kan tillhandahållas med andra filleverantörer för att hantera filer från andra platser. Mer information finns i UseStaticFiles som fortfarande behövs med UseFileServer för wwwroot (dotnet/AspNetCore.Docs #15578).

Ange HTTP-svarshuvuden

Använd StaticFileOptions för att ange HTTP-svarshuvuden. Förutom att konfigurera middleware för statiska filer för att servera statiska filer anger följande kod Cache-Control HTTP-huvudet till 604 800 sekunder (en vecka).

Namnområden för följande API:

using Microsoft.AspNetCore.Http;

I pipelinen för bearbetning av begäranden efter det befintliga anropet till antingen MapStaticAssets (.NET 9 eller senare) eller UseStaticFiles (.NET 8 eller tidigare):

app.UseStaticFiles(new StaticFileOptions
{
    OnPrepareResponse = ctx =>
    {
        ctx.Context.Response.Headers.Append(
            "Cache-Control", "public, max-age=604800");
    }
});

Stor samling tillgångar

När du hanterar stora samlingar av tillgångar, som anses vara cirka 1 000 eller fler tillgångar, rekommenderar vi att du använder en bundler för att minska det slutliga antalet tillgångar som hanteras av appen eller kombinera MapStaticAssets med UseStaticFiles.

MapStaticAssets läser ivrigt in de förberäknade metadata som samlas in under byggprocessen för resurserna för att stödja komprimering, cachelagring och fingeravtryck. De här funktionerna kostar mer minnesanvändning av appen. För tillgångar som används ofta är det vanligtvis värt kostnaderna. För tillgångar som inte används ofta kanske kompromissen inte är värd kostnaderna.

Om du inte använder paketering rekommenderar vi att du kombinerar MapStaticAssets med UseStaticFiles. I följande exempel visas metoden.

I projektfilen (.csproj) används MSBuild-egenskapen StaticWebAssetEndpointExclusionPattern för att filtrera slutpunkter från det slutliga manifestet för MapStaticAssets. Exkluderade filer hanteras av UseStaticFiles och drar inte nytta av komprimering, cachelagring eller fingerprinting.

När du anger värdet för StaticWebAssetEndpointExclusionPatternbehåller du $(StaticWebAssetEndpointExclusionPattern) för att behålla ramverkets standardundantagsmönster. Lägg till ytterligare mönster i en semikolonavgränsad lista.

I följande exempel lägger exkluderings-patten till de statiska filerna i lib/icons mappen, som representerar en hypotetisk uppsättning ikoner:

<StaticWebAssetEndpointExclusionPattern>
  $(StaticWebAssetEndpointExclusionPattern);lib/icons/**
</StaticWebAssetEndpointExclusionPattern>

Efter bearbetning av HTTPS-omdirigeringsmiddleware (app.UseHttpsRedirection();) i filen Program:

app.UseStaticFiles();

app.UseAuthorization();

app.MapStaticAssets();

Manifest för statiska tillgångar

MapStaticAssets levererar resurser från ett manifest över statiska resurser i stället för att genomsöka webbroten under körning. Manifestet genereras vid bygg- och publiceringstid och registrerar de statiska webbtillgångar som identifierats för appen, tillsammans med metadata som innehålls fingeravtryck, Content-Type rubriker, cachelagringshuvuden och förberäknade komprimerade representationer (Gzip och Brotli). Vid körning läser MapStaticAssets manifestet, registrerar en slutpunkt för varje resurs och levererar de optimerade svaren.

Manifestet genereras i build-utdatakatalogen vid byggtiden. Dess filnamn baseras på projektets sammansättningsnamn (till exempel {ASSEMBLY NAME}.staticwebassets.endpoints.json, där {ASSEMBLY NAME} platshållaren är appens MSBuild-värde AssemblyName ). Information om hur du anger ett manifest från en annan plats finns i avsnittet Ange ett anpassat manifest för statiska filer .

Eftersom MapStaticAssets endast hanterar tillgångar som anges i manifestet hanteras inte filer som inte ingår i manifestet av MapStaticAssets. Filer ingår inte i manifestet när de är:

  • Finns utanför webbroten vid kompilering, till exempel filer som serveras från disk, inbäddade resurser eller en anpassad WebRootPath som anges vid körning.
  • Exkluderas från manifestet med StaticWebAssetEndpointExclusionPattern MSBuild-egenskapen (se avsnittet Stor samling med resurser).

Om du vill servera filer som inte finns i manifestet anropar du UseStaticFiles, som serverar filer direkt från webbrotkatalogen under körning. Det är också därför som det krävs ett anrop till UseStaticFiles för att servera standarddokument med MapStaticAssets.

Auktorisering av statisk fil

När en app antar en reservauktoriseringsprincip krävs auktorisering för alla begäranden som inte uttryckligen anger en auktoriseringsprincip. Det här kravet omfattar begäranden för statiska filer efter att mellanprogram för auktorisering bearbetar begäranden. Om du vill tillåta anonym åtkomst till statiska filer tillämpar du AllowAnonymousAttribute på slutpunktsbyggaren för statiska filer:

app.MapStaticAssets().Add(endpointBuilder => 
    endpointBuilder.Metadata.Add(new AllowAnonymousAttribute()));

När en app antar en reservauktoriseringsprincip krävs auktorisering för alla begäranden som inte uttryckligen anger en auktoriseringsprincip, inklusive begäranden om statiska filer efter begäranden om mellanprogram för auktorisering. Mallarna ASP.NET Core tillåter anonym åtkomst till statiska filer genom att anropa UseStaticFiles innan du anropar UseAuthorization. De flesta appar följer det här mönstret. När mellanprogrammet för statiska filer anropas före auktoriseringsmellanprogrammet:

  • Inga auktoriseringskontroller utförs på de statiska filerna.
  • Statiska filer som tillhandahålls av mellanprogrammet för statiska filer, till exempel filer i webbroten (vanligtvis wwwroot), är offentligt åtkomliga.

Så här hanterar du statiska filer baserat på auktorisering:

  • Bekräfta att appen anger principen för reservautentisering för att kräva autentiserade användare.
  • Lagra den statiska filen utanför appens webbrot.
  • När du har anropat UseAuthorization ska du anropa UseStaticFiles och ange sökvägen till mappen med statiska filer utanför webbroten.

Namnområden för följande API:

using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.FileProviders;

Tjänstregistrering:

builder.Services.AddAuthorization(options =>
{
    options.FallbackPolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
});

I pipelinen för bearbetning av begäran efter anropet till UseAuthorization:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "SecureStaticFiles")),
    RequestPath = "/static-files"
});

Namnområden för följande API:

using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.FileProviders;

I Startup.ConfigureServices:

services.AddAuthorization(options =>
{
    options.FallbackPolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
});

I Startup.Configure efter anropet till UseAuthorization:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.ContentRootPath, "SecureStaticFiles")),
    RequestPath = "/static-files"
});

I föregående kod kräver reservauktoriseringsprincipen autentiserade användare. Slutpunkter, till exempel kontroller och Razor Sidor, som anger sina egna auktoriseringskrav använder inte fall-back-auktoriseringsprincipen. Till exempel använder Razor sidor, kontrollanter eller åtgärdsmetoder med [AllowAnonymous] eller [Authorize(PolicyName="MyPolicy")] det använda auktoriseringsattributet i stället för reservauktoriseringspolicyn.

RequireAuthenticatedUser lägger till DenyAnonymousAuthorizationRequirement till den aktuella instansen, vilket framtvingar att den aktuella användaren autentiseras.

Statiska resurser som lagras i appens webbrotkatalog är offentligt tillgängliga eftersom standardmiddleware för statiska filer (UseStaticFiles) anropas före UseAuthorization. Statiska tillgångar i SecureStaticFiles mappen kräver autentisering.

En alternativ metod för att hantera filer baserat på auktorisering är att:

  • Lagra filerna utanför webbroten och alla kataloger som är åtkomliga för mellanprogram för statiska filer.
  • Hantera filerna via en åtgärdsmetod som auktorisering tillämpas på och returnera ett FileResult objekt.

Från en Razor sida (Pages/BannerImage.cshtml.cs):

public class BannerImageModel : PageModel
{
    private readonly IWebHostEnvironment _env;

    public BannerImageModel(IWebHostEnvironment env) => _env = env;

    public PhysicalFileResult OnGet()
    {
        var filePath = Path.Combine(
            _env.ContentRootPath, "SecureStaticFiles", "images", "red-rose.jpg");

        return PhysicalFile(filePath, "image/jpeg");
    }
}

Från en styrenhet (Controllers/HomeController.cs):

[Authorize]
public IActionResult BannerImage()
{
    var filePath = Path.Combine(
        _env.ContentRootPath, "SecureStaticFiles", "images", "red-rose.jpg");

    return PhysicalFile(filePath, "image/jpeg");
}

Föregående metod kräver en sida eller slutpunkt per fil.

Följande vägslutpunktsexempel returnerar filer för autentiserade användare.

I filen Program:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AuthenticatedUsers", b => b.RequireAuthenticatedUser());
});

...

app.MapGet("/files/{fileName}", IResult (string fileName) => 
{
    var filePath = GetOrCreateFilePath(fileName);

    if (File.Exists(filePath))
    {
        return TypedResults.PhysicalFile(filePath, fileName);
    }

    return TypedResults.NotFound("No file found with the supplied file name");
})
.WithName("GetFileByName")
.RequireAuthorization("AuthenticatedUsers");

Följande exempel på routningsslutpunkt laddar upp filer för autentiserade användare i administratörsrollen (admin).

I filen Program:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AdminsOnly", b => b.RequireRole("admin"));
});

...

// IFormFile uses memory buffer for uploading. For handling large 
// files, use streaming instead. See the *File uploads* article
// in the ASP.NET Core documentation:
// https://learn.microsoft.com/aspnet/core/mvc/models/file-uploads
app.MapPost("/files", async (IFormFile file, LinkGenerator linker, 
    HttpContext context) =>
{
    // Don't rely on the value in 'file.FileName', as it's only metadata that can 
    // be manipulated by the end-user. Consider 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");

I Startup.ConfigureServices:

services.AddAuthorization(options =>
{
    options.AddPolicy("AuthenticatedUsers", b => b.RequireAuthenticatedUser());
});

I Startup.Configure:

app.MapGet("/files/{fileName}", IResult (string fileName) => 
{
    var filePath = GetOrCreateFilePath(fileName);

    if (File.Exists(filePath))
    {
        return TypedResults.PhysicalFile(filePath, fileName);
    }

    return TypedResults.NotFound("No file found with the supplied file name");
})
.WithName("GetFileByName")
.RequireAuthorization("AuthenticatedUsers");

Följande kod laddar upp filer för autentiserade användare i administratörsrollen (admin).

I Startup.ConfigureServices:

services.AddAuthorization(options =>
{
    options.AddPolicy("AdminsOnly", b => b.RequireRole("admin"));
});

I Startup.Configure:

// IFormFile uses memory buffer for uploading. For handling large 
// files, use streaming instead. See the *File uploads* article
// in the ASP.NET Core documentation:
// https://learn.microsoft.com/aspnet/core/mvc/models/file-uploads
app.MapPost("/files", async (IFormFile file, LinkGenerator linker, 
    HttpContext context) =>
{
    // Don't rely on the value in 'file.FileName', as it's only metadata that can 
    // be manipulated by the end-user. Consider 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");

Katalogbläddring

Katalogbläddring tillåter kataloglistning inom angivna kataloger.

Av säkerhetsskäl är katalogbläddring inaktiverat som standard. Mer information finns i Säkerhetsöverväganden för statiska filer.

Aktivera katalogbläddring med hjälp av följande API:er:

I följande exempel:

  • En images mapp i appens rot innehåller bilder för katalogbläddring.
  • Begärandesökvägen för att bläddra bland bilderna är /DirectoryImages.
  • Om du anropar UseStaticFiles och ställer in FileProvider av StaticFileOptions så att du kan visa webbläsarlänkar till de enskilda filerna.

Namnområden för följande API:

using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;

Tjänstregistrering:

builder.Services.AddDirectoryBrowser();

I pipelinen för bearbetning av begäranden efter det befintliga anropet till antingen MapStaticAssets (.NET 9 eller senare) eller UseStaticFiles (.NET 8 eller tidigare):

var fileProvider = new PhysicalFileProvider(
    Path.Combine(builder.Environment.WebRootPath, "images"));
var requestPath = "/DirectoryImages";

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = fileProvider,
    RequestPath = requestPath
});

app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
    FileProvider = fileProvider,
    RequestPath = requestPath
});

Namnområden för följande API:

using Microsoft.Extensions.FileProviders;
using System.IO;

I Startup.ConfigureServices:

services.AddDirectoryBrowser();

I Startup.Configure efter det befintliga anropet till UseStaticFiles:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.WebRootPath, "images")),
    RequestPath = "/DirectoryImages"
});

app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.WebRootPath, "images")),
    RequestPath = "/DirectoryImages"
});

Föregående kod tillåter katalogbläddring i mappen wwwroot/images med hjälp av URL:en https://{HOST}/DirectoryImages med länkar till varje fil och mapp, där platshållaren {HOST} representerar värden.

AddDirectoryBrowser lägger till tjänster som krävs av katalogbläddringsmellanprogrammet, inklusive HtmlEncoder. Dessa tjänster kan läggas till av andra anrop, till exempel AddRazorPages, men vi rekommenderar att du anropar AddDirectoryBrowser för att säkerställa att tjänsterna läggs till.

Hantera standarddokument

Om du anger en standardsida får besökare en startpunkt på en webbplats. Om du vill hantera en standardfil från wwwroot utan att begärande-URL:en måste innehålla filens namn anropar UseDefaultFiles du metoden.

UseDefaultFiles är en URL-omskrivare som inte serverar filen. Den skriver om begärande-URL:en till standarddokumentet (till exempel / till /index.html) och en annan komponent hanterar filen.

Eftersom MapStaticAssets hanterar tillgångar som identifieras vid byggtiden via slutpunktsroutning, hanterar de inte standarddokument på egen hand. Anropa UseDefaultFiles för att skriva om begäran, följt av UseStaticFiles för att hantera den omskrivna begäran för standarddokumentet:

app.UseDefaultFiles();
app.UseStaticFiles();
app.MapStaticAssets();

Viktigt!

Om du bara UseDefaultFiles konfigurerar och MapStaticAssets (utan UseStaticFiles) returneras svaret 404 – Hittades inte för en begäran till /. Det beror på att minimal värd lägger till mellanprogram för routning i början av pipelinen för bearbetning av begäran, så slutpunktsroutning matchar begäran innan UseDefaultFiles den skrivs om till standarddokumentet. Problemet är särskilt uppenbart när webbroten ändras till en anpassad sökväg med hjälp av WebRootPath, eftersom filer i en anpassad webbrot inte ingår i manifestet över statiska resurser vid byggtiden som MapStaticAssets serverar. Lägg till ett anrop till UseStaticFiles efter UseDefaultFiles, som du ser i föregående exempel, för att hantera standarddokument.

I pipelinen för bearbetning av begäran före det befintliga anropet till UseStaticFiles:

app.UseDefaultFiles();

Med UseDefaultFilessöker begäranden till en mapp i wwwroot efter:

  • default.htm
  • default.html
  • index.htm
  • index.html

Den första filen som hittades i listan hanteras som om begäran innehöll filens namn. Webbläsarens URL fortsätter att återspegla den begärda URI:n.

Följande kod ändrar standardfilnamnet till default-document.html:

var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("default-document.html");
app.UseDefaultFiles(options);

Kombinera statiska filer, standarddokument och katalogbläddring

UseFileServer kombinerar funktionerna i UseStaticFiles, UseDefaultFilesoch eventuellt UseDirectoryBrowser.

I pipelinen för bearbetning av begäran efter det befintliga anropet till antingen MapStaticAssets (.NET 9 eller senare) eller UseStaticFiles (.NET 8 eller tidigare) anropar du UseFileServer för att aktivera servering av statiska filer och standardfilen:

app.UseFileServer();

Katalogbläddring är inte aktiverat för föregående exempel.

Följande kod möjliggör servering av statiska filer, standardfilen och katalogbläddring.

Tjänstregistrering:

builder.Services.AddDirectoryBrowser();

I pipelinen för bearbetning av begäranden efter det befintliga anropet till UseStaticFiles:

app.UseFileServer(enableDirectoryBrowsing: true);

I Startup.ConfigureServices:

services.AddDirectoryBrowser();

I Startup.Configure efter det befintliga anropet till UseStaticFiles:

app.UseFileServer(enableDirectoryBrowsing: true);

För värdadressen (/) UseFileServer returnerar standard-HTML-dokumentet före standardsidan Razor (Pages/Index.cshtml) eller MVC-standardvyn (Home/Index.cshtml).

Överväg följande kataloghierarki:

  • wwwroot
    • css
    • images
    • js
  • ExtraStaticFiles
    • images
      • logo.png
    • default.html

Följande kod möjliggör servering av statiska filer, standardfilen och katalogbläddring av ExtraStaticFiles.

Namnområden för följande API:

using Microsoft.Extensions.FileProviders;

Tjänstregistrering:

builder.Services.AddDirectoryBrowser();

I pipelinen för bearbetning av begäranden efter det befintliga anropet till UseStaticFiles:

app.UseFileServer(new FileServerOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles")),
    RequestPath = "/static-files",
    EnableDirectoryBrowsing = true
});

Namnområden för följande API:

using Microsoft.Extensions.FileProviders;
using System.IO;

I Startup.ConfigureServices:

services.AddDirectoryBrowser();

I Startup.Configure efter det befintliga anropet till UseStaticFiles:

app.UseFileServer(new FileServerOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.ContentRootPath, "ExtraStaticFiles")),
    RequestPath = "/static-files",
    EnableDirectoryBrowsing = true
});

AddDirectoryBrowser måste anropas när EnableDirectoryBrowsing egenskapsvärdet är true.

Med hjälp av föregående filhierarki och kod matchar URL:er enligt följande tabell ( {HOST} platshållaren är värden).

URI Svarsfil
https://{HOST}/static-files/images/logo.png ExtraStaticFiles/images/logo.png
https://{HOST}/static-files ExtraStaticFiles/default.html

Om det inte finns någon fil med standardnamn i ExtraStaticFiles-katalogen returnerar https://{HOST}/static-files kataloglistan med klickbara länkar, där platshållaren {HOST} är värd.

UseDefaultFiles och UseDirectoryBrowser utför en omdirigering på klientsidan från mål-URI:n utan en avslutande / till mål-URI:n med en avslutande /. Till exempel från https://{HOST}/static-files (ingen avslutande /) till https://{HOST}/static-files/ (innehåller en avslutande /). Relativa URL:er i ExtraStaticFiles katalogen är ogiltiga utan ett avslutande snedstreck (/) om inte RedirectToAppendTrailingSlash alternativet DefaultFilesOptions används.

Mappa filnamnstillägg till MIME-typer

Note

Vägledning som gäller för Blazor appar finns i ASP.NET Core statiska filerBlazor.

Använd FileExtensionContentTypeProvider.Mappings för att lägga till eller ändra filnamnstillägg till MIME-innehållstypmappningar.

Note

FileExtensionContentTypeProvider är inte trådsäker för samtidiga skrivningar. Dess interna mappningsordlista är en standard Dictionary<string, string> utan synkronisering. Providerns mappningar är avsedda att konfigureras en gång vid start. Om endast läsåtgärder (sökningar) utförs efteråt, kan leverantören utan risk registreras som en singleton. Lägg inte till, ta bort eller ändra mappningar när providern används av samtidiga begäranden.

I följande exempel mappas flera filnamnstillägg till kända MIME-typer. Tillägget .rtf ersätts och .mp4 tas bort:

using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;

...

// 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
});

När du har flera alternativ för statiska filer att konfigurera kan du ange providern med hjälp av StaticFileOptions:

var provider = new FileExtensionContentTypeProvider();

...

builder.Services.Configure<StaticFileOptions>(options =>
{
    options.ContentTypeProvider = provider;
});

app.UseStaticFiles();

I Startup.Configure:

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 = "/images",
    ContentTypeProvider = provider
});

app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.WebRootPath, "images")),
    RequestPath = "/images"
});

Mer information finns i MIME-innehållstyper.

Innehållstyper som inte är standard

Det statiska filmellanprogrammet förstår nästan 400 kända filinnehållstyper. Om användaren begär en fil med en okänd filtyp skickar det statiska filmellanprogrammet begäran till nästa mellanprogram i pipelinen. Om inget mellanprogram hanterar begäran returneras ett 404 Hittades inte svar. Om katalogbläddring är aktiverat visas en länk till filen i en kataloglista.

Följande kod gör det möjligt att hantera okända innehållstyper och renderar den okända filen som en bild:

app.UseStaticFiles(new StaticFileOptions
{
    ServeUnknownFileTypes = true,
    DefaultContentType = "image/png"
});

Med föregående kod returneras en begäran om en fil med en okänd innehållstyp som en bild.

Warning

Att aktivera ServeUnknownFileTypes är en säkerhetsrisk. Den är inaktiverad som standard och dess användning rekommenderas inte. Mappa filnamnstillägg till MIME-typer är ett säkrare alternativ till att hantera filer med tillägg som inte är standard.

Ange ett anpassat manifest för statiska filer

Om staticAssetsManifestPath är null används IHostEnvironment.ApplicationName för att hitta manifestet. Du kan också ange en fullständig sökväg till manifestfilen. Om en relativ sökväg används söker ramverket efter filen i AppContext.BaseDirectory.

Säkerhetsöverväganden för statiska filer

Warning

UseDirectoryBrowser och UseStaticFiles kan läcka hemligheter. Vi rekommenderar starkt att du inaktiverar katalogbläddring i produktion. Granska noggrant vilka kataloger som är aktiverade via UseStaticFiles eller UseDirectoryBrowser. Hela katalogen och dess underkataloger blir offentligt tillgängliga. Lagra filer som är lämpliga för att betjäna allmänheten i en dedikerad katalog, till exempel <content_root>/wwwroot. Avgränsa dessa filer från MVC-vyer, Razor sidor, konfigurationsfiler osv.

  • URL:er för innehåll som exponeras med UseDirectoryBrowser och UseStaticFiles omfattas av skiftlägeskänsligheten och teckenbegränsningarna för det underliggande filsystemet. Windows är till exempel skiftlägesokänsligt, men macOS och Linux är det inte.

  • ASP.NET Core-appar som finns i IIS använder ASP.NET Core Module för att vidarebefordra alla begäranden till appen, inklusive statiska filbegäranden. Den statiska IIS-filhanteraren används inte och har ingen chans att hantera begäranden.

  • Slutför följande steg i IIS-hanteraren för att ta bort den statiska IIS-filhanteraren på server- eller webbplatsnivå:

    1. Gå till funktionen Moduler.
    2. Välj StaticFileModule i listan.
    3. Klicka på Ta bort i sidofältet Åtgärder.

Warning

Om den statiska IIS-filhanteraren är aktiverad och ASP.NET Core Module har konfigurerats felaktigt, hanteras statiska filer. Detta inträffar till exempel om web.config filen inte har distribuerats.

  • Placera kodfiler, inklusive .cs och .cshtml, utanför appprojektets webbrot. Därför skapas en logisk separation mellan appens innehåll på klientsidan och serverbaserad kod. Detta förhindrar att kod på serversidan läcker ut.

MSBuild-egenskaper

Följande tabeller visar msBuild-egenskaper och metadatabeskrivningar för statiska filer.

Fastighet Description
EnableDefaultCompressedItems Aktiverar standardkomprimering: inkludera/exkludera mönster.
CompressionIncludePatterns Semikolonavgränsad lista över filmönster som ska ingå för komprimering.
CompressionExcludePatterns Semikolonavgränsad lista över filmönster som ska undantas från komprimering.
EnableDefaultCompressionFormats Aktiverar standardkomprimeringsformat (Gzip och Brotli).
BuildCompressionFormats Komprimeringsformat som ska användas under bygget.
PublishCompressionFormats Komprimeringsformat som ska användas under publiceringen.
DisableBuildCompression Inaktiverar komprimering under bygget.
CompressDiscoveredAssetsDuringBuild Komprimerar identifierade tillgångar under bygget.
BrotliCompressionLevel Komprimeringsnivå för Brotli-algoritmen.
StaticWebAssetBuildCompressAllAssets Komprimerar alla resurser under byggprocessen, inte bara resurser som identifieras eller beräknas under en byggprocess.
StaticWebAssetPublishCompressAllAssets Komprimerar alla tillgångar vid utgivning, inte bara tillgångar som upptäcks eller beräknas under en kompilering.
Fastighet Description
StaticWebAssetBasePath Grundläggande URL-sökväg för alla tillgångar i ett bibliotek.
StaticWebAssetsFingerprintContent Aktiverar fingeravtryck för innehåll för cache-busting.
StaticWebAssetFingerprintingEnabled Aktiverar fingeravtrycksfunktionen för statiska webbtillgångar.
StaticWebAssetsCacheDefineStaticWebAssetsEnabled Aktiverar cachelagring för statiska webbtillgångsdefinitioner.
StaticWebAssetEndpointExclusionPattern Mönster för exkludering av slutpunkter.
Artikelgrupp Description Metainformation
StaticWebAssetContentTypeMapping Mappar filmönster till innehållstyper och cachehuvuden för slutpunkter. Pattern, CachePriority
StaticWebAssetFingerprintPattern Definierar mönster för att tillämpa fingeravtryck på statiska webbtillgångar för cachelagring. Pattern, Expression

Metadatabeskrivningar:

  • Pattern: Ett globmönster som används för att matcha filer. För StaticWebAssetContentTypeMappingmatchar den filer för att fastställa deras innehållstyp (till exempel *.js för JavaScript-filer). För StaticWebAssetFingerprintPatternidentifierar den filer med flera tillägg som kräver särskild fingeravtrycksbehandling (till exempel *.lib.module.js).

  • Cache: Anger Cache-Control rubrikvärdet för den matchade innehållstypen. Detta styr webbläsarens cachelagringsbeteende (till exempel max-age=3600, must-revalidate för mediefiler).

  • Priority: Styr prioritet när flera StaticWebAssetContentTypeMapping objekt matchar samma fil. Högre numeriska värden har företräde framför lägre värden. Priority måste anges.

  • Expression: Definierar hur fingeravtrycket infogas i filnamnet. Standardvärdet är #[.{FINGERPRINT}], vilket infogar fingeravtrycket ({FINGERPRINT} platshållare) före förlängningen.

I följande exempel mappas bitmappsfilmönstret (.bmp) till image/bmp innehållstypen med {CACHE HEADER} platshållaren som representerar Cache-Control rubriken som ska användas för slutpunkter som inte har fingeravtryck:

<ItemGroup>
  <StaticWebAssetContentTypeMapping Include="image/bmp" Cache="{CACHE HEADER}"
    Pattern="*.bmp" Priority="1" />
</ItemGroup>

Konfigurationsalternativ för körtid

I följande tabell beskrivs konfigurationsalternativ för körningstid.

Konfigurationsnyckel Description
ReloadStaticAssetsAtRuntime Möjliggör hotladdning av statiska resurser under utvecklingstid: serverar ändrade webbrotsfiler (wwwroot) (beräknar om ETag och komprimerar om det behövs) istället för förutbestämda manifestversioner. Standardvärdet är endast aktiverat när du hanterar ett byggmanifest om det inte uttryckligen anges.
DisableStaticAssetNotFoundRuntimeFallback När true används, inaktiverar det den återställningsslutpunkt som hanterar nyligen tillagda filer som inte finns i byggmanifestet. När false är närvarande eller saknas, använder en fil-existeringskontrollerad {**path} reservmetod (GET/HEAD) en varning och levererar filen med en beräknad ETag.
EnableStaticAssetsDevelopmentCaching När true bevaras de ursprungliga Cache-Control rubrikerna på tillgångsbeskrivningar. När false är närvarande eller frånvarande skrivs Cache-Control-rubriker om till no-cache för att undvika aggressiv klientcachelagring under utveckling.
EnableStaticAssetsDevelopmentIntegrity När true, behåller integritetsegenskaper på tillgångsbeskrivningar. När false är frånvarande, tar det bort integritetsegenskapen för att förhindra felmatchningar när filer ändras under utvecklingen.

Ytterligare resurser