Statické soubory v ASP.NET Core

Poznámka:

Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Upozorňující

Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Důležité

Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.

Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Autor: Rick Anderson

Statické soubory, jako jsou HTML, CSS, obrázky a JavaScript, jsou prostředky, které aplikace ASP.NET Core ve výchozím nastavení obsluhuje přímo klientům.

Pokyny Blazor ke statickým souborům, které přidávají nebo nahrazují pokyny v tomto článku, najdete v tématu ASP.NET Core Blazor statické soubory.

Poskytování statických souborů

Statické soubory jsou uložené v kořenovém adresáři projektu. Výchozí adresář je {content root}/wwwroot, ale lze ho UseWebRoot změnit pomocí metody. Další informace najdete v tématu Kořenový adresář obsahu a kořenový adresář webu.

Metoda CreateBuilder nastaví kořen obsahu na aktuální adresář:

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();

Statické soubory jsou přístupné prostřednictvím cesty vzhledem k webovému kořenovému adresáři. Šablony projektů webové aplikace například obsahují několik složek ve wwwroot složce:

  • wwwroot
    • css
    • js
    • lib

Zvažte aplikaci se souborem wwwroot/images/MyImage.jpg . Formát identifikátoru URI pro přístup k souboru ve images složce je https://<hostname>/images/<image_file_name>. Například https://localhost:5001/images/MyImage.jpg

MapStaticAssets

Vytváření výkonných webových aplikací vyžaduje optimalizaci doručování prostředků do prohlížeče. Mezi možné optimalizace patří:

  • Posílejte daný prostředek jednou, dokud se soubor nezmění nebo prohlížeč vymaže jeho mezipaměť. Nastavte záhlaví značky ETag .
  • Zabrání prohlížeči v používání starých nebo zastaralých prostředků po aktualizaci aplikace. Nastavte hlavičku Naposledy změněno .
  • Nastavte správné hlavičky ukládání do mezipaměti.
  • Použijte middleware pro ukládání do mezipaměti.
  • Pokud je to možné, obsluhujte komprimované verze prostředků.
  • Použijte CDN k poskytování prostředků blíže k uživateli.
  • Minimalizujte velikost prostředků obsluhovaných v prohlížeči. Tato optimalizace nezahrnuje minifikace.

MapStaticAssets jsou konvence koncového bodu směrování, které optimalizují doručování statických prostředků v aplikaci. Je navržená tak, aby fungovala se všemi architekturami uživatelského rozhraní, včetně Blazor, Razor Pages a MVC.

UseStaticFiles také obsluhuje statické soubory, ale neposkytuje stejnou úroveň optimalizace jako MapStaticAssets. Porovnání a MapStaticAssetsnaleznete v tématu Optimalizace doručování statických webových UseStaticFiles prostředků .

Obsluha souborů ve webovém kořenovém adresáři

Výchozí šablony webové aplikace volají metodu MapStaticAssets Program.cs, která umožňuje obsluhovat statické soubory:

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();

Přetížení metody bez UseStaticFiles parametrů označuje soubory ve webovém kořenovém adresáři jako rezervované. Následující odkazy na značky wwwroot/images/MyImage.jpg:

<img src="~/images/MyImage.jpg" class="img" alt="My image" />

V předchozím kódu znak tilda ~ odkazuje na kořenový adresář webu.

Obsluha souborů mimo kořenový adresář webu

Představte si hierarchii adresářů, ve které se statické soubory mají obsluhovat mimo webovou kořenovou složku:

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

Požadavek má přístup k red-rose.jpg souboru konfigurací middlewaru statického souboru následujícím způsobem:

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();

V předchozím kódu je hierarchie adresáře MyStaticFiles veřejně zpřístupněna prostřednictvím segmentu URI StaticFiles . Žádost o https://<hostname>/StaticFiles/images/red-rose.jpg poskytnutí red-rose.jpg souboru.

Následující odkazy na značky MyStaticFiles/images/red-rose.jpg:

<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />

Pokud chcete obsluhovat soubory z více umístění, přečtěte si téma Obsluha souborů z více umístění.

Nastavení hlaviček odpovědí HTTP

Objekt StaticFileOptions lze použít k nastavení hlaviček odpovědi HTTP. Kromě konfigurace statického souboru obsluhujícího z webového kořenového adresáře nastaví následující kód hlavičku Cache-Control :

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();

 var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
 app.UseStaticFiles(new StaticFileOptions
 {
     OnPrepareResponse = ctx =>
     {
         ctx.Context.Response.Headers.Append(
              "Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
     }
 });

app.UseAuthorization();

app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();

app.Run();

Předchozí kód veřejně zpřístupní statické soubory v místní mezipaměti po dobu jednoho týdne.

Statická autorizace souborů

Šablony ASP.NET Core volají MapStaticAssets před voláním UseAuthorization. Většina aplikací tento vzor dodržuje. Při zavolání middlewaru statického souboru před autorizačním middlewarem:

  • Statické soubory neprovádí žádné kontroly autorizace.
  • Statické soubory obsluhované middlewarem statických souborů, jako jsou například soubory v části wwwroot, jsou veřejně přístupné.

Obsluha statických souborů na základě autorizace:

  • Ukládejte je mimo wwwroot.
  • Volání UseStaticFiles, určení cesty po volání UseAuthorization.
  • Nastavte záložní zásady autorizace.
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();

V předchozím kódu vyžadují, aby se ověřili všichni uživatelé. Koncové body, jako jsou kontrolery, Razor stránky atd., které určují vlastní požadavky na autorizaci, nepoužívají záložní zásady autorizace. Například Razor Pages, controllers, or action methods with [AllowAnonymous] or [Authorize(PolicyName="MyPolicy")] use the applied authorization attribute, than the fallback authorization policy.

RequireAuthenticatedUser přidá DenyAnonymousAuthorizationRequirement do aktuální instance, která vynucuje ověření aktuálního uživatele.

Statické prostředky wwwroot jsou veřejně přístupné, protože výchozí middleware statického souboru (app.UseStaticFiles();) je volána před UseAuthentication. Statické prostředky ve složce MyStaticFiles vyžadují ověření. Ukázkový kód to demonstruje.

Alternativním přístupem k poskytování souborů na základě autorizace je:

  • Uložte je mimo wwwroot adresář přístupný pro middleware statického souboru.

  • Obsloužíte je prostřednictvím metody akce, na kterou se použije autorizace, a vrátí FileResult objekt:

    [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");
        }
    }
    

Předchozí přístup vyžaduje stránku nebo koncový bod pro každý soubor. Následující kód vrátí soubory nebo nahraje soubory pro ověřené uživatele:

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 v předchozí ukázce používá vyrovnávací paměť pro nahrání. Pro zpracování velkých souborů použijte streamování. Viz Nahrání velkých souborů se streamováním.

Kompletní ukázku najdete ve složce StaticFileAuth Na GitHubu.

Procházení adresářů

Procházení adresářů umožňuje výpis adresářů v zadaných adresářích.

Procházení adresářů je ve výchozím nastavení zakázané z bezpečnostních důvodů. Další informace najdete v tématu Důležité informace o zabezpečení statických souborů.

Povolte procházení adresářů pomocí AddDirectoryBrowser a 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();

Předchozí kód umožňuje procházení adresáře složky wwwroot/images pomocí adresy URL https://<hostname>/MyImagess odkazy na každý soubor a složku:

procházení adresářů

AddDirectoryBrowserpřidává služby vyžadované middlewarem procházení adresářů, včetně HtmlEncoder. Tyto služby mohou být přidány jinými voláními, například AddRazorPages, ale doporučujeme volat AddDirectoryBrowser , aby se zajistilo, že jsou služby přidány ve všech aplikacích.

Obsluha výchozích dokumentů

Nastavení výchozí stránky poskytuje návštěvníkům výchozí bod na webu. Pokud chcete, aby se výchozí soubor wwwroot zobrazoval bez vyžadování adresy URL požadavku, aby obsahoval název souboru, zavolejte metodu UseDefaultFiles :

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseDefaultFiles();

app.UseStaticFiles();
app.UseAuthorization();

app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();

app.Run();

UseDefaultFiles před odesláním výchozího souboru musí být volána UseStaticFiles . UseDefaultFiles je autor adresy URL, který soubor neslouží.

Při UseDefaultFileshledání žádostí o složku wwwroot :

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

První soubor nalezený ze seznamu se obsluhuje, jako by požadavek obsahoval název souboru. Adresa URL prohlížeče bude i nadále odrážet požadovaný identifikátor URI. Například v ukázkové aplikaci požadavek na https://localhost:<port>/def/ obsluhu default.html z wwwroot/defaplikace .

Následující kód změní výchozí název souboru na mydefault.html:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();

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

app.UseStaticFiles();

app.UseAuthorization();

app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();

app.Run();

UseFileServer pro výchozí dokumenty

UseFileServer kombinuje funkce UseStaticFiles, UseDefaultFilesa volitelně UseDirectoryBrowser.

Volání app.UseFileServer umožňující obsluhu statických souborů a výchozího souboru Procházení adresářů není povolené:

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();

Následující kód umožňuje obsluhu statických souborů, výchozí soubor a procházení adresářů:

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();

Zvažte následující hierarchii adresářů:

  • wwwroot
    • css
    • images
    • js
  • MyStaticFiles
    • defaultFiles
      • default.html
      • image3.png
    • images
      • MyImage.jpg

Následující kód umožňuje obsluhu statických souborů, výchozí soubor a procházení MyStaticFilesadresáře:

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 musí být volána, pokud EnableDirectoryBrowsing je truehodnota vlastnosti .

Pomocí předchozí hierarchie souborů a kódu se adresy URL přeloží takto:

Identifikátor URI Response
https://<hostname>/StaticFiles/images/MyImage.jpg MyStaticFiles/images/MyImage.jpg
https://<hostname>/StaticFiles výpis adresáře
https://<hostname>/StaticFiles/defaultFiles MyStaticFiles/defaultFiles/default.html
https://<hostname>/StaticFiles/defaultFiles/image3.png MyStaticFiles/defaultFiles//image3.png

Pokud v adresáři MyStaticFiles neexistuje žádný výchozí pojmenovaný soubor, https://<hostname>/StaticFiles vrátí seznam adresářů s odkazy, na které lze kliknout:

Seznam statických souborů

UseDefaultFiles a UseDirectoryBrowser proveďte přesměrování na straně klienta z cílového identifikátoru URI bez koncového / na cílový identifikátor URI s koncovým /identifikátorem . Například z https://<hostname>/StaticFiles do https://<hostname>/StaticFiles/. Relativní adresy URL v adresáři StaticFiles nejsou platné bez koncového lomítka (/), pokud RedirectToAppendTrailingSlash není použita možnostDefaultFilesOptions.

FileExtensionContentTypeProvider

Třída FileExtensionContentTypeProvider obsahuje vlastnost Mappings , která slouží jako mapování přípon souborů na typy obsahu MIME. V následující ukázce se namapuje několik přípon souborů na známé typy MIME. Rozšíření .rtf se nahradí a .mp4 se odebere:

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();

Viz typy obsahu MIME.

Nestandardní typy obsahu

Middleware statického souboru rozumí téměř 400 známým typům obsahu souboru. Pokud uživatel požádá o soubor s neznámým typem souboru, middleware statického souboru předá požadavek do dalšího middlewaru v kanálu. Pokud požadavek nezpracuje žádný middleware, vrátí se odpověď 404 Nenalezena . Pokud je povolené procházení adresářů, zobrazí se v seznamu adresářů odkaz na soubor.

Následující kód umožňuje obsluhovat neznámé typy a vykreslit neznámý soubor jako obrázek:

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();

V předchozím kódu se jako obrázek vrátí požadavek na soubor s neznámým typem obsahu.

Upozorňující

Povolení ServeUnknownFileTypes je bezpečnostní riziko. Ve výchozím nastavení je zakázaný a jeho použití se nedoporučuje. FileExtensionContentTypeProvider poskytuje bezpečnější alternativu k poskytování souborů s nestandardními příponami.

Obsluha souborů z více umístění

Podívejte se na následující Razor stránku, na které se /MyStaticFiles/image3.png soubor zobrazuje:

@page

<p> Test /MyStaticFiles/image3.png</p>

<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">

UseStaticFiles a UseFileServer ve výchozím nastavení na zprostředkovatele souborů odkazující na wwwroot. Další instance a UseFileServer mohou být poskytovány UseStaticFiles s jinými poskytovateli souborů pro obsluhu souborů z jiných umístění. Následující příklad volá UseStaticFiles dvakrát obsluhovat soubory z obou wwwroot a MyStaticFiles:

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

Pomocí předchozího kódu:

  • Soubor /MyStaticFiles/image3.png se zobrazí.
  • Pomocné rutiny AppendVersion značek obrázků se nepoužijí, protože pomocné rutiny značek závisí na WebRootFileProvider. WebRootFileProvider nebyla aktualizována tak, aby zahrnovala MyStaticFiles složku.

Následující kód aktualizuje WebRootFileProvider, který umožňuje pomocné rutině značky obrázku poskytnout verzi:

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();

Poznámka:

Předchozí přístup platí pro Razor aplikace Pages a MVC. Pokyny, které platí pro Blazor Web Apps, najdete v tématu ASP.NET Core Blazor statických souborů.

Důležité informace o zabezpečení statických souborů

Upozorňující

UseDirectoryBrowser a UseStaticFiles může vytékat tajné kódy. Zakázání procházení adresářů v produkčním prostředí se důrazně doporučuje. Pečlivě zkontrolujte, které adresáře jsou povoleny prostřednictvím UseStaticFiles nebo UseDirectoryBrowser. Celý adresář a jeho podadresáři jsou veřejně přístupné. Ukládat soubory vhodné pro poskytování veřejnosti ve vyhrazeném adresáři, například <content_root>/wwwroot. Tyto soubory oddělte od zobrazení MVC, Razor stránek, konfiguračních souborů atd.

  • Adresy URL pro obsah vystavený s příponou UseDirectoryBrowser, UseStaticFilesa MapStaticAssets podléhají omezení velikosti a velikosti písmen základního systému souborů. Windows například nerozlišuje malá a velká písmena, ale macOS a Linux nejsou.

  • ASP.NET aplikace Core hostované ve službě IIS používají modul ASP.NET Core k předávání všech požadavků do aplikace, včetně požadavků na statické soubory. Obslužná rutina statického souboru služby IIS se nepoužívá a nemá šanci zpracovat požadavky.

  • Pomocí následujících kroků ve Správci služby IIS odeberte obslužnou rutinu statického souboru služby IIS na úrovni serveru nebo webu:

    1. Přejděte na funkci Moduly .
    2. V seznamu vyberte StaticFileModule .
    3. Na bočním panelu Akcí klikněte na Odebrat.

Upozorňující

Pokud je povolená obslužná rutina statického souboru služby IIS a ASP.NET základní modul je správně nakonfigurovaný, obsluhují se statické soubory. K tomu dochází například v případě, že soubor web.config není nasazený.

  • Umístěte soubory kódu, včetně .cs a .cshtml, mimo webovou kořenovou složku projektu aplikace. Logické oddělení se proto vytvoří mezi obsahem na straně klienta aplikace a serverovým kódem. Tím zabráníte úniku kódu na straně serveru.

Obsluha souborů mimo webroot aktualizací IWebHostEnvironment.WebRootPath

Je-li IWebHostEnvironment.WebRootPath nastavena na jinou složku než wwwroot:

  • Ve vývojovém prostředí se statické prostředky nalezené v obou wwwroot a aktualizovaných IWebHostEnvironment.WebRootPath prostředcích obsluhují z wwwroot.
  • V jakémkoli jiném prostředí než ve vývoji se z aktualizované IWebHostEnvironment.WebRootPath složky obsluhují duplicitní statické prostředky.

Představte si webovou aplikaci vytvořenou s prázdnou webovou šablonou:

  • Index.html Obsahující soubor v wwwroot a wwwroot-custom.

  • S následujícím aktualizovaným Program.cs souborem, který nastaví WebRootPath = "wwwroot-custom":

    var builder = WebApplication.CreateBuilder(new WebApplicationOptions
    {
        Args = args,
        // Look for static files in "wwwroot-custom"
        WebRootPath = "wwwroot-custom"
    });
    
    var app = builder.Build();
    
    app.UseDefaultFiles();
    app.MapStaticAssets();
    
    app.Run();
    

V předchozím kódu požaduje /:

  • V návratu vývojového prostředí wwwroot/Index.html
  • V jakémkoli jiném prostředí, než je vrácení vývoje wwwroot-custom/Index.html

Pokud chcete zajistit vrácení prostředků wwwroot-custom , použijte jeden z následujících přístupů:

  • Odstraňte duplicitní pojmenované prostředky v wwwrootsouboru .

  • Properties/launchSettings.json Nastavit "ASPNETCORE_ENVIRONMENT" na libovolnou jinou hodnotu než "Development".

  • Úplné zakázání statických webových prostředků nastavením <StaticWebAssetsEnabled>false</StaticWebAssetsEnabled> v souboru projektu. UPOZORNĚNÍ, zakázání statických webových prostředků zakáže Razor knihovny tříd.

  • Do souboru projektu přidejte následující KÓD XML:

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

Následující kód aktualizuje IWebHostEnvironment.WebRootPath hodnotu, která není vývojová, a zaručuje, že duplicitní obsah se vrátí spíše wwwrootnež wwwroot-custom z:

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();

Další materiály

Autor: Rick Anderson

Statické soubory, jako jsou HTML, CSS, obrázky a JavaScript, jsou prostředky, které aplikace ASP.NET Core ve výchozím nastavení obsluhuje přímo klientům.

Poskytování statických souborů

Statické soubory jsou uložené v kořenovém adresáři projektu. Výchozí adresář je {content root}/wwwroot, ale lze ho UseWebRoot změnit pomocí metody. Další informace najdete v tématu Kořenový adresář obsahu a kořenový adresář webu.

Metoda CreateBuilder nastaví kořen obsahu na aktuální adresář:

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();

Statické soubory jsou přístupné prostřednictvím cesty vzhledem k webovému kořenovému adresáři. Šablony projektů webové aplikace například obsahují několik složek ve wwwroot složce:

  • wwwroot
    • css
    • js
    • lib

Zvažte vytvoření složky wwwroot/images a přidání wwwroot/images/MyImage.jpg souboru. Formát identifikátoru URI pro přístup k souboru ve images složce je https://<hostname>/images/<image_file_name>. Například https://localhost:5001/images/MyImage.jpg

Obsluha souborů ve webovém kořenovém adresáři

Výchozí šablony webové aplikace volají metodu UseStaticFiles Program.cs, která umožňuje obsluhovat statické soubory:

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();

Přetížení metody bez UseStaticFiles parametrů označuje soubory ve webovém kořenovém adresáři jako rezervované. Následující odkazy na značky wwwroot/images/MyImage.jpg:

<img src="~/images/MyImage.jpg" class="img" alt="My image" />

V předchozím kódu znak tilda ~ odkazuje na kořenový adresář webu.

Obsluha souborů mimo kořenový adresář webu

Představte si hierarchii adresářů, ve které se statické soubory mají obsluhovat mimo webovou kořenovou složku:

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

Požadavek má přístup k red-rose.jpg souboru konfigurací middlewaru statického souboru následujícím způsobem:

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();

V předchozím kódu je hierarchie adresáře MyStaticFiles veřejně zpřístupněna prostřednictvím segmentu URI StaticFiles . Žádost o https://<hostname>/StaticFiles/images/red-rose.jpg poskytnutí red-rose.jpg souboru.

Následující odkazy na značky MyStaticFiles/images/red-rose.jpg:

<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />

Pokud chcete obsluhovat soubory z více umístění, přečtěte si téma Obsluha souborů z více umístění.

Nastavení hlaviček odpovědí HTTP

Objekt StaticFileOptions lze použít k nastavení hlaviček odpovědi HTTP. Kromě konfigurace statického souboru obsluhujícího z webového kořenového adresáře nastaví následující kód hlavičku Cache-Control :

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();

var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
    OnPrepareResponse = ctx =>
    {
        ctx.Context.Response.Headers.Append(
             "Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
    }
});

app.UseAuthorization();

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.Run();

Předchozí kód veřejně zpřístupní statické soubory v místní mezipaměti po dobu jednoho týdne (604800 sekund).

Statická autorizace souborů

Šablony ASP.NET Core volají UseStaticFiles před voláním UseAuthorization. Většina aplikací tento vzor dodržuje. Při zavolání middlewaru statického souboru před autorizačním middlewarem:

  • Statické soubory neprovádí žádné kontroly autorizace.
  • Statické soubory obsluhované middlewarem statických souborů, jako jsou například soubory v části wwwroot, jsou veřejně přístupné.

Obsluha statických souborů na základě autorizace:

  • Ukládejte je mimo wwwroot.
  • Volání UseStaticFiles, určení cesty po volání UseAuthorization.
  • Nastavte záložní zásady autorizace.
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();

V předchozím kódu vyžadují, aby se ověřili všichni uživatelé. Koncové body, jako jsou kontrolery, Razor stránky atd., které určují vlastní požadavky na autorizaci, nepoužívají záložní zásady autorizace. Například Razor Pages, controllers, or action methods with [AllowAnonymous] or [Authorize(PolicyName="MyPolicy")] use the applied authorization attribute, than the fallback authorization policy.

RequireAuthenticatedUser přidá DenyAnonymousAuthorizationRequirement do aktuální instance, která vynucuje ověření aktuálního uživatele.

Statické prostředky wwwroot jsou veřejně přístupné, protože výchozí middleware statického souboru (app.UseStaticFiles();) je volána před UseAuthentication. Statické prostředky ve složce MyStaticFiles vyžadují ověření. Ukázkový kód to demonstruje.

Alternativním přístupem k poskytování souborů na základě autorizace je:

  • Uložte je mimo wwwroot adresář přístupný pro middleware statického souboru.

  • Obsloužíte je prostřednictvím metody akce, na kterou se použije autorizace, a vrátí FileResult objekt:

    [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");
        }
    }
    

Předchozí přístup vyžaduje stránku nebo koncový bod pro každý soubor. Následující kód vrátí soubory nebo nahraje soubory pro ověřené uživatele:

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://video2.skills-academy.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();

Kompletní ukázku najdete ve složce StaticFileAuth Na GitHubu.

Procházení adresářů

Procházení adresářů umožňuje výpis adresářů v zadaných adresářích.

Procházení adresářů je ve výchozím nastavení zakázané z bezpečnostních důvodů. Další informace najdete v tématu Důležité informace o zabezpečení statických souborů.

Povolte procházení adresářů pomocí AddDirectoryBrowser a 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();

Předchozí kód umožňuje procházení adresáře složky wwwroot/images pomocí adresy URL https://<hostname>/MyImagess odkazy na každý soubor a složku:

procházení adresářů

AddDirectoryBrowserpřidává služby vyžadované middlewarem procházení adresářů, včetně HtmlEncoder. Tyto služby mohou být přidány jinými voláními, například AddRazorPages, ale doporučujeme volat AddDirectoryBrowser , aby se zajistilo, že jsou služby přidány ve všech aplikacích.

Obsluha výchozích dokumentů

Nastavení výchozí stránky poskytuje návštěvníkům výchozí bod na webu. Pokud chcete, aby se výchozí soubor wwwroot zobrazoval bez vyžadování adresy URL požadavku, aby obsahoval název souboru, zavolejte metodu UseDefaultFiles :

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseDefaultFiles();

app.UseStaticFiles();
app.UseAuthorization();

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.Run();

UseDefaultFiles před odesláním výchozího souboru musí být volána UseStaticFiles . UseDefaultFiles je autor adresy URL, který soubor neslouží.

Při UseDefaultFileshledání žádostí o složku wwwroot :

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

První soubor nalezený ze seznamu se obsluhuje, jako by požadavek obsahoval název souboru. Adresa URL prohlížeče bude i nadále odrážet požadovaný identifikátor URI.

Následující kód změní výchozí název souboru na mydefault.html:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();

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

app.UseStaticFiles();

app.UseAuthorization();

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.Run();

UseFileServer pro výchozí dokumenty

UseFileServer kombinuje funkce UseStaticFiles, UseDefaultFilesa volitelně UseDirectoryBrowser.

Volání app.UseFileServer umožňující obsluhu statických souborů a výchozího souboru Procházení adresářů není povolené:

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();

Následující kód umožňuje obsluhu statických souborů, výchozí soubor a procházení adresářů:

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();

Zvažte následující hierarchii adresářů:

  • wwwroot
    • css
    • images
    • js
  • MyStaticFiles
    • images
      • MyImage.jpg
    • default.html

Následující kód umožňuje obsluhu statických souborů, výchozí soubor a procházení MyStaticFilesadresáře:

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 musí být volána, pokud EnableDirectoryBrowsing je truehodnota vlastnosti .

Pomocí předchozí hierarchie souborů a kódu se adresy URL přeloží takto:

Identifikátor URI Response
https://<hostname>/StaticFiles/images/MyImage.jpg MyStaticFiles/images/MyImage.jpg
https://<hostname>/StaticFiles MyStaticFiles/default.html

Pokud v adresáři MyStaticFiles neexistuje žádný výchozí pojmenovaný soubor, https://<hostname>/StaticFiles vrátí seznam adresářů s odkazy, na které lze kliknout:

Seznam statických souborů

UseDefaultFiles a UseDirectoryBrowser proveďte přesměrování na straně klienta z cílového identifikátoru URI bez koncového / na cílový identifikátor URI s koncovým /identifikátorem . Například z https://<hostname>/StaticFiles do https://<hostname>/StaticFiles/. Relativní adresy URL v adresáři StaticFiles nejsou platné bez koncového lomítka (/), pokud RedirectToAppendTrailingSlash není použita možnostDefaultFilesOptions.

FileExtensionContentTypeProvider

Třída FileExtensionContentTypeProvider obsahuje Mappings vlastnost, která slouží jako mapování přípon souborů na typy obsahu MIME. V následující ukázce se namapuje několik přípon souborů na známé typy MIME. Rozšíření .rtf se nahradí a .mp4 se odebere:

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();

Viz typy obsahu MIME.

Nestandardní typy obsahu

Middleware statického souboru rozumí téměř 400 známým typům obsahu souboru. Pokud uživatel požádá o soubor s neznámým typem souboru, middleware statického souboru předá požadavek do dalšího middlewaru v kanálu. Pokud požadavek nezpracuje žádný middleware, vrátí se odpověď 404 Nenalezena . Pokud je povolené procházení adresářů, zobrazí se v seznamu adresářů odkaz na soubor.

Následující kód umožňuje obsluhovat neznámé typy a vykreslit neznámý soubor jako obrázek:

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();

V předchozím kódu se jako obrázek vrátí požadavek na soubor s neznámým typem obsahu.

Upozorňující

Povolení ServeUnknownFileTypes je bezpečnostní riziko. Ve výchozím nastavení je zakázaný a jeho použití se nedoporučuje. FileExtensionContentTypeProvider poskytuje bezpečnější alternativu k poskytování souborů s nestandardními příponami.

Obsluha souborů z více umístění

Podívejte se na následující Razor stránku, na které se /MyStaticFiles/image3.png soubor zobrazuje:

@page

<p> Test /MyStaticFiles/image3.png</p>

<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">

UseStaticFiles a UseFileServer ve výchozím nastavení na zprostředkovatele souborů odkazující na wwwroot. Další instance a UseFileServer mohou být poskytovány UseStaticFiles s jinými poskytovateli souborů pro obsluhu souborů z jiných umístění. Následující příklad volá UseStaticFiles dvakrát obsluhovat soubory z obou wwwroot a MyStaticFiles:

app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});

Pomocí předchozího kódu:

  • Soubor /MyStaticFiles/image3.png se zobrazí.
  • Pomocné rutiny AppendVersion značek obrázků se nepoužijí, protože pomocné rutiny značek závisí na WebRootFileProvider. WebRootFileProvider nebyla aktualizována tak, aby zahrnovala MyStaticFiles složku.

Následující kód aktualizuje WebRootFileProvider, který umožňuje pomocné rutině značky obrázku poskytnout verzi:

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();

Poznámka:

Předchozí přístup platí pro Razor aplikace Pages a MVC. Pokyny, které platí pro Blazor Web Apps, najdete v tématu ASP.NET Core Blazor statických souborů.

Důležité informace o zabezpečení statických souborů

Upozorňující

UseDirectoryBrowser a UseStaticFiles může vytékat tajné kódy. Zakázání procházení adresářů v produkčním prostředí se důrazně doporučuje. Pečlivě zkontrolujte, které adresáře jsou povoleny prostřednictvím UseStaticFiles nebo UseDirectoryBrowser. Celý adresář a jeho podadresáři jsou veřejně přístupné. Ukládat soubory vhodné pro poskytování veřejnosti ve vyhrazeném adresáři, například <content_root>/wwwroot. Tyto soubory oddělte od zobrazení MVC, Razor stránek, konfiguračních souborů atd.

  • Adresy URL pro obsah vystavený obsahem UseDirectoryBrowser a UseStaticFiles podléhají omezení velikosti písmen a znaků základního systému souborů. Windows například nerozlišuje malá a velká písmena, ale macOS a Linux nejsou.

  • ASP.NET aplikace Core hostované ve službě IIS používají modul ASP.NET Core k předávání všech požadavků do aplikace, včetně požadavků na statické soubory. Obslužná rutina statického souboru služby IIS se nepoužívá a nemá šanci zpracovat požadavky.

  • Pomocí následujících kroků ve Správci služby IIS odeberte obslužnou rutinu statického souboru služby IIS na úrovni serveru nebo webu:

    1. Přejděte na funkci Moduly .
    2. V seznamu vyberte StaticFileModule .
    3. Na bočním panelu Akcí klikněte na Odebrat.

Upozorňující

Pokud je povolená obslužná rutina statického souboru služby IIS a ASP.NET základní modul je správně nakonfigurovaný, obsluhují se statické soubory. K tomu dochází například v případě, že soubor web.config není nasazený.

  • Umístěte soubory kódu, včetně .cs a .cshtml, mimo webovou kořenovou složku projektu aplikace. Logické oddělení se proto vytvoří mezi obsahem na straně klienta aplikace a serverovým kódem. Tím zabráníte úniku kódu na straně serveru.

Obsluha souborů mimo webroot aktualizací IWebHostEnvironment.WebRootPath

Je-li IWebHostEnvironment.WebRootPath nastavena na jinou složku než wwwroot:

  • Ve vývojovém prostředí se statické prostředky nalezené v obou wwwroot a aktualizovaných IWebHostEnvironment.WebRootPath prostředcích obsluhují z wwwroot.
  • V jakémkoli jiném prostředí než ve vývoji se z aktualizované IWebHostEnvironment.WebRootPath složky obsluhují duplicitní statické prostředky.

Představte si webovou aplikaci vytvořenou s prázdnou webovou šablonou:

  • Index.html Obsahující soubor v wwwroot a wwwroot-custom.

  • S následujícím aktualizovaným Program.cs souborem, který nastaví WebRootPath = "wwwroot-custom":

    var builder = WebApplication.CreateBuilder(new WebApplicationOptions
    {
        Args = args,
        // Look for static files in "wwwroot-custom"
        WebRootPath = "wwwroot-custom"
    });
    
    var app = builder.Build();
    
    app.UseDefaultFiles();
    app.UseStaticFiles();
    
    app.Run();
    

V předchozím kódu požaduje /:

  • V návratu vývojového prostředí wwwroot/Index.html
  • V jakémkoli jiném prostředí, než je vrácení vývoje wwwroot-custom/Index.html

Pokud chcete zajistit vrácení prostředků wwwroot-custom , použijte jeden z následujících přístupů:

  • Odstraňte duplicitní pojmenované prostředky v wwwrootsouboru .

  • Properties/launchSettings.json Nastavit "ASPNETCORE_ENVIRONMENT" na libovolnou jinou hodnotu než "Development".

  • Úplné zakázání statických webových prostředků nastavením <StaticWebAssetsEnabled>false</StaticWebAssetsEnabled> v souboru projektu. UPOZORNĚNÍ, zakázání statických webových prostředků zakáže Razor knihovny tříd.

  • Do souboru projektu přidejte následující KÓD JSON:

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

Následující kód aktualizuje IWebHostEnvironment.WebRootPath hodnotu, která není vývojová, a zaručuje, že duplicitní obsah se vrátí spíše wwwrootnež wwwroot-custom z:

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();

Další materiály

Autoři: Rick Anderson a Kirk Larkin

Statické soubory, jako jsou HTML, CSS, obrázky a JavaScript, jsou prostředky, které aplikace ASP.NET Core ve výchozím nastavení obsluhuje přímo klientům.

Poskytování statických souborů

Statické soubory jsou uložené v kořenovém adresáři projektu. Výchozí adresář je {content root}/wwwroot, ale lze ho UseWebRoot změnit pomocí metody. Další informace najdete v tématu Kořenový adresář obsahu a kořenový adresář webu.

Metoda CreateBuilder nastaví kořen obsahu na aktuální adresář:

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();

Statické soubory jsou přístupné prostřednictvím cesty vzhledem k webovému kořenovému adresáři. Šablony projektů webové aplikace například obsahují několik složek ve wwwroot složce:

  • wwwroot
    • css
    • js
    • lib

Zvažte vytvoření složky wwwroot/images a přidání wwwroot/images/MyImage.jpg souboru. Formát identifikátoru URI pro přístup k souboru ve images složce je https://<hostname>/images/<image_file_name>. Například https://localhost:5001/images/MyImage.jpg

Obsluha souborů ve webovém kořenovém adresáři

Výchozí šablony webové aplikace volají metodu UseStaticFiles Program.cs, která umožňuje obsluhovat statické soubory:

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();

Přetížení metody bez UseStaticFiles parametrů označuje soubory ve webovém kořenovém adresáři jako rezervované. Následující odkazy na značky wwwroot/images/MyImage.jpg:

<img src="~/images/MyImage.jpg" class="img" alt="My image" />

V předchozím kódu znak tilda ~ odkazuje na kořenový adresář webu.

Obsluha souborů mimo kořenový adresář webu

Představte si hierarchii adresářů, ve které se statické soubory mají obsluhovat mimo webovou kořenovou složku:

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

Požadavek má přístup k red-rose.jpg souboru konfigurací middlewaru statického souboru následujícím způsobem:

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();

V předchozím kódu je hierarchie adresáře MyStaticFiles veřejně zpřístupněna prostřednictvím segmentu URI StaticFiles . Žádost o https://<hostname>/StaticFiles/images/red-rose.jpg poskytnutí red-rose.jpg souboru.

Následující odkazy na značky MyStaticFiles/images/red-rose.jpg:

<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />

Pokud chcete obsluhovat soubory z více umístění, přečtěte si téma Obsluha souborů z více umístění.

Nastavení hlaviček odpovědí HTTP

Objekt StaticFileOptions lze použít k nastavení hlaviček odpovědi HTTP. Kromě konfigurace statického souboru obsluhujícího z webového kořenového adresáře nastaví následující kód hlavičku Cache-Control :

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();

var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
    OnPrepareResponse = ctx =>
    {
        ctx.Context.Response.Headers.Append(
             "Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
    }
});

app.UseAuthorization();

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.Run();

Předchozí kód veřejně zpřístupní statické soubory v místní mezipaměti po dobu jednoho týdne (604800 sekund).

Statická autorizace souborů

Šablony ASP.NET Core volají UseStaticFiles před voláním UseAuthorization. Většina aplikací tento vzor dodržuje. Při zavolání middlewaru statického souboru před autorizačním middlewarem:

  • Statické soubory neprovádí žádné kontroly autorizace.
  • Statické soubory obsluhované middlewarem statických souborů, jako jsou například soubory v části wwwroot, jsou veřejně přístupné.

Obsluha statických souborů na základě autorizace:

  • Ukládejte je mimo wwwroot.
  • Volání UseStaticFiles, určení cesty po volání UseAuthorization.
  • Nastavte záložní zásady autorizace.
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();

V předchozím kódu vyžadují, aby se ověřili všichni uživatelé. Koncové body, jako jsou kontrolery, Razor stránky atd., které určují vlastní požadavky na autorizaci, nepoužívají záložní zásady autorizace. Například Razor Pages, controllers, or action methods with [AllowAnonymous] or [Authorize(PolicyName="MyPolicy")] use the applied authorization attribute, than the fallback authorization policy.

RequireAuthenticatedUser přidá DenyAnonymousAuthorizationRequirement do aktuální instance, která vynucuje ověření aktuálního uživatele.

Statické prostředky wwwroot jsou veřejně přístupné, protože výchozí middleware statického souboru (app.UseStaticFiles();) je volána před UseAuthentication. Statické prostředky ve složce MyStaticFiles vyžadují ověření. Ukázkový kód to demonstruje.

Alternativním přístupem k poskytování souborů na základě autorizace je:

  • Uložte je mimo wwwroot adresář přístupný pro middleware statického souboru.
  • Obsloužíte je prostřednictvím metody akce, na kterou se použije autorizace, a vrátí FileResult objekt:
[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");
    }
}

Procházení adresářů

Procházení adresářů umožňuje výpis adresářů v zadaných adresářích.

Procházení adresářů je ve výchozím nastavení zakázané z bezpečnostních důvodů. Další informace najdete v tématu Důležité informace o zabezpečení statických souborů.

Povolte procházení adresářů pomocí AddDirectoryBrowser a 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();

Předchozí kód umožňuje procházení adresáře složky wwwroot/images pomocí adresy URL https://<hostname>/MyImagess odkazy na každý soubor a složku:

procházení adresářů

AddDirectoryBrowserpřidává služby vyžadované middlewarem procházení adresářů, včetně HtmlEncoder. Tyto služby mohou být přidány jinými voláními, například AddRazorPages, ale doporučujeme volat AddDirectoryBrowser , aby se zajistilo, že jsou služby přidány ve všech aplikacích.

Obsluha výchozích dokumentů

Nastavení výchozí stránky poskytuje návštěvníkům výchozí bod na webu. Pokud chcete, aby se výchozí soubor wwwroot zobrazoval bez vyžadování adresy URL požadavku, aby obsahoval název souboru, zavolejte metodu UseDefaultFiles :

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseDefaultFiles();

app.UseStaticFiles();
app.UseAuthorization();

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.Run();

UseDefaultFiles před odesláním výchozího souboru musí být volána UseStaticFiles . UseDefaultFiles je autor adresy URL, který soubor neslouží.

Při UseDefaultFileshledání žádostí o složku wwwroot :

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

První soubor nalezený ze seznamu se obsluhuje, jako by požadavek obsahoval název souboru. Adresa URL prohlížeče bude i nadále odrážet požadovaný identifikátor URI.

Následující kód změní výchozí název souboru na mydefault.html:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();

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

app.UseStaticFiles();

app.UseAuthorization();

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.Run();

UseFileServer pro výchozí dokumenty

UseFileServer kombinuje funkce UseStaticFiles, UseDefaultFilesa volitelně UseDirectoryBrowser.

Volání app.UseFileServer umožňující obsluhu statických souborů a výchozího souboru Procházení adresářů není povolené:

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();

Následující kód umožňuje obsluhu statických souborů, výchozí soubor a procházení adresářů:

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();

Zvažte následující hierarchii adresářů:

  • wwwroot
    • css
    • images
    • js
  • MyStaticFiles
    • images
      • MyImage.jpg
    • default.html

Následující kód umožňuje obsluhu statických souborů, výchozí soubor a procházení MyStaticFilesadresáře:

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 musí být volána, pokud EnableDirectoryBrowsing je truehodnota vlastnosti .

Pomocí předchozí hierarchie souborů a kódu se adresy URL přeloží takto:

Identifikátor URI Response
https://<hostname>/StaticFiles/images/MyImage.jpg MyStaticFiles/images/MyImage.jpg
https://<hostname>/StaticFiles MyStaticFiles/default.html

Pokud v adresáři MyStaticFiles neexistuje žádný výchozí pojmenovaný soubor, https://<hostname>/StaticFiles vrátí seznam adresářů s odkazy, na které lze kliknout:

Seznam statických souborů

UseDefaultFiles a UseDirectoryBrowser proveďte přesměrování na straně klienta z cílového identifikátoru URI bez koncového / na cílový identifikátor URI s koncovým /identifikátorem . Například z https://<hostname>/StaticFiles do https://<hostname>/StaticFiles/. Relativní adresy URL v adresáři StaticFiles nejsou platné bez koncového lomítka (/), pokud RedirectToAppendTrailingSlash není použita možnostDefaultFilesOptions.

FileExtensionContentTypeProvider

Třída FileExtensionContentTypeProvider obsahuje Mappings vlastnost, která slouží jako mapování přípon souborů na typy obsahu MIME. V následující ukázce se namapuje několik přípon souborů na známé typy MIME. Rozšíření .rtf se nahradí a .mp4 se odebere:

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();

Viz typy obsahu MIME.

Nestandardní typy obsahu

Middleware statického souboru rozumí téměř 400 známým typům obsahu souboru. Pokud uživatel požádá o soubor s neznámým typem souboru, middleware statického souboru předá požadavek do dalšího middlewaru v kanálu. Pokud požadavek nezpracuje žádný middleware, vrátí se odpověď 404 Nenalezena . Pokud je povolené procházení adresářů, zobrazí se v seznamu adresářů odkaz na soubor.

Následující kód umožňuje obsluhovat neznámé typy a vykreslit neznámý soubor jako obrázek:

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();

V předchozím kódu se jako obrázek vrátí požadavek na soubor s neznámým typem obsahu.

Upozorňující

Povolení ServeUnknownFileTypes je bezpečnostní riziko. Ve výchozím nastavení je zakázaný a jeho použití se nedoporučuje. FileExtensionContentTypeProvider poskytuje bezpečnější alternativu k poskytování souborů s nestandardními příponami.

Obsluha souborů z více umístění

Podívejte se na následující Razor stránku, na které se /MyStaticFiles/image3.png soubor zobrazuje:

@page

<p> Test /MyStaticFiles/image3.png</p>

<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">

UseStaticFiles a UseFileServer ve výchozím nastavení na zprostředkovatele souborů odkazující na wwwroot. Další instance a UseFileServer mohou být poskytovány UseStaticFiles s jinými poskytovateli souborů pro obsluhu souborů z jiných umístění. Následující příklad volá UseStaticFiles dvakrát obsluhovat soubory z obou wwwroot a MyStaticFiles:

app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});

Pomocí předchozího kódu:

  • Soubor /MyStaticFiles/image3.png se zobrazí.
  • Pomocné rutiny AppendVersion značek obrázků se nepoužijí, protože pomocné rutiny značek závisí na WebRootFileProvider. WebRootFileProvider nebyla aktualizována tak, aby zahrnovala MyStaticFiles složku.

Následující kód aktualizuje WebRootFileProvider, který umožňuje pomocné rutině značky obrázku poskytnout verzi:

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();

Důležité informace o zabezpečení statických souborů

Upozorňující

UseDirectoryBrowser a UseStaticFiles může vytékat tajné kódy. Zakázání procházení adresářů v produkčním prostředí se důrazně doporučuje. Pečlivě zkontrolujte, které adresáře jsou povoleny prostřednictvím UseStaticFiles nebo UseDirectoryBrowser. Celý adresář a jeho podadresáři jsou veřejně přístupné. Ukládat soubory vhodné pro poskytování veřejnosti ve vyhrazeném adresáři, například <content_root>/wwwroot. Tyto soubory oddělte od zobrazení MVC, Razor stránek, konfiguračních souborů atd.

  • Adresy URL pro obsah vystavený obsahem UseDirectoryBrowser a UseStaticFiles podléhají omezení velikosti písmen a znaků základního systému souborů. Windows například nerozlišuje malá a velká písmena, ale macOS a Linux nejsou.

  • ASP.NET aplikace Core hostované ve službě IIS používají modul ASP.NET Core k předávání všech požadavků do aplikace, včetně požadavků na statické soubory. Obslužná rutina statického souboru služby IIS se nepoužívá a nemá šanci zpracovat požadavky.

  • Pomocí následujících kroků ve Správci služby IIS odeberte obslužnou rutinu statického souboru služby IIS na úrovni serveru nebo webu:

    1. Přejděte na funkci Moduly .
    2. V seznamu vyberte StaticFileModule .
    3. Na bočním panelu Akcí klikněte na Odebrat.

Upozorňující

Pokud je povolená obslužná rutina statického souboru služby IIS a ASP.NET základní modul je správně nakonfigurovaný, obsluhují se statické soubory. K tomu dochází například v případě, že soubor web.config není nasazený.

  • Umístěte soubory kódu, včetně .cs a .cshtml, mimo webovou kořenovou složku projektu aplikace. Logické oddělení se proto vytvoří mezi obsahem na straně klienta aplikace a serverovým kódem. Tím zabráníte úniku kódu na straně serveru.

Obsluha souborů mimo webroot aktualizací IWebHostEnvironment.WebRootPath

Je-li IWebHostEnvironment.WebRootPath nastavena na jinou složku než wwwroot:

  • Ve vývojovém prostředí se statické prostředky nalezené v obou wwwroot a aktualizovaných IWebHostEnvironment.WebRootPath prostředcích obsluhují z wwwroot.
  • V jakémkoli jiném prostředí než ve vývoji se z aktualizované IWebHostEnvironment.WebRootPath složky obsluhují duplicitní statické prostředky.

Představte si webovou aplikaci vytvořenou s prázdnou webovou šablonou:

  • Index.html Obsahující soubor v wwwroot a wwwroot-custom.

  • S následujícím aktualizovaným Program.cs souborem, který nastaví WebRootPath = "wwwroot-custom":

    var builder = WebApplication.CreateBuilder(new WebApplicationOptions
    {
        Args = args,
        // Look for static files in "wwwroot-custom"
        WebRootPath = "wwwroot-custom"
    });
    
    var app = builder.Build();
    
    app.UseDefaultFiles();
    app.UseStaticFiles();
    
    app.Run();
    

V předchozím kódu požaduje /:

  • V návratu vývojového prostředí wwwroot/Index.html
  • V jakémkoli jiném prostředí, než je vrácení vývoje wwwroot-custom/Index.html

Pokud chcete zajistit vrácení prostředků wwwroot-custom , použijte jeden z následujících přístupů:

  • Odstraňte duplicitní pojmenované prostředky v wwwrootsouboru .

  • Properties/launchSettings.json Nastavit "ASPNETCORE_ENVIRONMENT" na libovolnou jinou hodnotu než "Development".

  • Úplné zakázání statických webových prostředků nastavením <StaticWebAssetsEnabled>false</StaticWebAssetsEnabled> v souboru projektu. UPOZORNĚNÍ, zakázání statických webových prostředků zakáže Razor knihovny tříd.

  • Do souboru projektu přidejte následující KÓD JSON:

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

Následující kód aktualizuje IWebHostEnvironment.WebRootPath hodnotu, která není vývojová, a zaručuje, že duplicitní obsah se vrátí spíše wwwrootnež wwwroot-custom z:

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();

Další materiály

Autoři: Rick Anderson a Kirk Larkin

Statické soubory, jako jsou HTML, CSS, obrázky a JavaScript, jsou prostředky, které aplikace ASP.NET Core ve výchozím nastavení obsluhuje přímo klientům.

Zobrazení nebo stažení ukázkového kódu (postup stažení)

Poskytování statických souborů

Statické soubory jsou uložené v kořenovém adresáři projektu. Výchozí adresář je {content root}/wwwroot, ale lze ho UseWebRoot změnit pomocí metody. Další informace najdete v tématu Kořenový adresář obsahu a kořenový adresář webu.

Metoda CreateDefaultBuilder nastaví kořen obsahu na aktuální adresář:

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

Předchozí kód byl vytvořen pomocí šablony webové aplikace.

Statické soubory jsou přístupné prostřednictvím cesty vzhledem k webovému kořenovému adresáři. Šablony projektů webové aplikace například obsahují několik složek ve wwwroot složce:

  • wwwroot
    • css
    • js
    • lib

Zvažte vytvoření složky wwwroot/images a přidání wwwroot/images/MyImage.jpg souboru. Formát identifikátoru URI pro přístup k souboru ve images složce je https://<hostname>/images/<image_file_name>. Například https://localhost:5001/images/MyImage.jpg

Obsluha souborů ve webovém kořenovém adresáři

Výchozí šablony webové aplikace volají metodu UseStaticFiles Startup.Configure, která umožňuje obsluhovat statické soubory:

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

Přetížení metody bez UseStaticFiles parametrů označuje soubory ve webovém kořenovém adresáři jako rezervované. Následující odkazy na značky wwwroot/images/MyImage.jpg:

<img src="~/images/MyImage.jpg" class="img" alt="My image" />

V předchozím kódu znak tilda ~/ odkazuje na kořenový adresář webu.

Obsluha souborů mimo kořenový adresář webu

Představte si hierarchii adresářů, ve které se statické soubory mají obsluhovat mimo webovou kořenovou složku:

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

Požadavek má přístup k red-rose.jpg souboru konfigurací middlewaru statického souboru následujícím způsobem:

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

V předchozím kódu je hierarchie adresáře MyStaticFiles veřejně zpřístupněna prostřednictvím segmentu URI StaticFiles . Žádost o https://<hostname>/StaticFiles/images/red-rose.jpg poskytnutí red-rose.jpg souboru.

Následující odkazy na značky MyStaticFiles/images/red-rose.jpg:

<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />

Nastavení hlaviček odpovědí HTTP

Objekt StaticFileOptions lze použít k nastavení hlaviček odpovědi HTTP. Kromě konfigurace statického souboru obsluhujícího z kořenového adresáře webu nastaví následující kód hlavičku Cache-Control :

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

Předchozí kód nastaví maximální věk na 604800 sekund (7 dní).

Hlavičky odpovědi zobrazující hlavičku Cache-Control byla přidána.

Statická autorizace souborů

Šablony ASP.NET Core volají UseStaticFiles před voláním UseAuthorization. Většina aplikací tento vzor dodržuje. Při zavolání middlewaru statického souboru před autorizačním middlewarem:

  • Statické soubory neprovádí žádné kontroly autorizace.
  • Statické soubory obsluhované middlewarem statických souborů, jako jsou například soubory v části wwwroot, jsou veřejně přístupné.

Obsluha statických souborů na základě autorizace:

  • Ukládejte je mimo wwwroot.
  • Volání UseStaticFiles, určení cesty po volání UseAuthorization.
  • Nastavte záložní zásady autorizace.
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.

V předchozím kódu vyžadují, aby se ověřili všichni uživatelé. Koncové body, jako jsou kontrolery, Razor stránky atd., které určují vlastní požadavky na autorizaci, nepoužívají záložní zásady autorizace. Například Razor Pages, controllers, or action methods with [AllowAnonymous] or [Authorize(PolicyName="MyPolicy")] use the applied authorization attribute, than the fallback authorization policy.

RequireAuthenticatedUser přidá DenyAnonymousAuthorizationRequirement do aktuální instance, která vynucuje ověření aktuálního uživatele.

Statické prostředky wwwroot jsou veřejně přístupné, protože výchozí middleware statického souboru (app.UseStaticFiles();) je volána před UseAuthentication. Statické prostředky ve složce MyStaticFiles vyžadují ověření. Ukázkový kód to demonstruje.

Alternativním přístupem k poskytování souborů na základě autorizace je:

  • Uložte je mimo wwwroot adresář přístupný pro middleware statického souboru.
  • Obsloužíte je prostřednictvím metody akce, na kterou se použije autorizace, a vrátí FileResult objekt:
[Authorize]
public IActionResult BannerImage()
{
    var filePath = Path.Combine(
        _env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");

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

Procházení adresářů

Procházení adresářů umožňuje výpis adresářů v zadaných adresářích.

Procházení adresářů je ve výchozím nastavení zakázané z bezpečnostních důvodů. Další informace najdete v tématu Důležité informace o zabezpečení statických souborů.

Povolte procházení adresářů pomocí:

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

Předchozí kód umožňuje procházení adresáře složky wwwroot/images pomocí adresy URL https://<hostname>/MyImagess odkazy na každý soubor a složku:

procházení adresářů

Obsluha výchozích dokumentů

Nastavení výchozí stránky poskytuje návštěvníkům výchozí bod na webu. Pokud chcete, aby se výchozí soubor wwwroot zobrazoval bez vyžadování adresy URL požadavku, aby obsahoval název souboru, zavolejte metodu UseDefaultFiles :

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();

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

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

UseDefaultFiles před odesláním výchozího souboru musí být volána UseStaticFiles . UseDefaultFiles je autor adresy URL, který soubor neslouží.

Při UseDefaultFileshledání žádostí o složku wwwroot :

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

První soubor nalezený ze seznamu se obsluhuje, jako by požadavek obsahoval název souboru. Adresa URL prohlížeče bude i nadále odrážet požadovaný identifikátor URI.

Následující kód změní výchozí název souboru na mydefault.html:

var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();

Následující kód ukazuje Startup.Configure předchozí kód:

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 pro výchozí dokumenty

UseFileServer kombinuje funkce UseStaticFiles, UseDefaultFilesa volitelně UseDirectoryBrowser.

Volání app.UseFileServer umožňující obsluhu statických souborů a výchozího souboru Procházení adresářů není povolené. Následující kód ukazujeStartup.Configure: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();
    });
}

Následující kód umožňuje obsluhu statických souborů, výchozí soubor a procházení adresářů:

app.UseFileServer(enableDirectoryBrowsing: true);

Následující kód ukazuje Startup.Configure předchozí kód:

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

Zvažte následující hierarchii adresářů:

  • wwwroot
    • css
    • images
    • js
  • MyStaticFiles
    • images
      • MyImage.jpg
    • default.html

Následující kód umožňuje obsluhu statických souborů, výchozí soubor a procházení MyStaticFilesadresáře:

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 musí být volána, pokud EnableDirectoryBrowsing je truehodnota vlastnosti .

Pomocí hierarchie souborů a předchozího kódu se adresy URL přeloží takto:

Identifikátor URI Response
https://<hostname>/StaticFiles/images/MyImage.jpg MyStaticFiles/images/MyImage.jpg
https://<hostname>/StaticFiles MyStaticFiles/default.html

Pokud v adresáři MyStaticFiles neexistuje žádný výchozí pojmenovaný soubor, https://<hostname>/StaticFiles vrátí seznam adresářů s odkazy, na které lze kliknout:

Seznam statických souborů

UseDefaultFiles a UseDirectoryBrowser proveďte přesměrování na straně klienta z cílového identifikátoru URI bez koncového / na cílový identifikátor URI s koncovým /identifikátorem . Například z https://<hostname>/StaticFiles do https://<hostname>/StaticFiles/. Relativní adresy URL v adresáři StaticFiles jsou neplatné bez koncového lomítka (/).

FileExtensionContentTypeProvider

Třída FileExtensionContentTypeProvider obsahuje Mappings vlastnost, která slouží jako mapování přípon souborů na typy obsahu MIME. V následující ukázce se namapuje několik přípon souborů na známé typy MIME. Rozšíření .rtf se nahradí a .mp4 se odebere:

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

Následující kód ukazuje Startup.Configure předchozí kód:

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

Viz typy obsahu MIME.

Nestandardní typy obsahu

Middleware statického souboru rozumí téměř 400 známým typům obsahu souboru. Pokud uživatel požádá o soubor s neznámým typem souboru, middleware statického souboru předá požadavek do dalšího middlewaru v kanálu. Pokud požadavek nezpracuje žádný middleware, vrátí se odpověď 404 Nenalezena . Pokud je povolené procházení adresářů, zobrazí se v seznamu adresářů odkaz na soubor.

Následující kód umožňuje obsluhovat neznámé typy a vykreslit neznámý soubor jako obrázek:

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

Následující kód ukazuje Startup.Configure předchozí kód:

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

V předchozím kódu se jako obrázek vrátí požadavek na soubor s neznámým typem obsahu.

Upozorňující

Povolení ServeUnknownFileTypes je bezpečnostní riziko. Ve výchozím nastavení je zakázaný a jeho použití se nedoporučuje. FileExtensionContentTypeProvider poskytuje bezpečnější alternativu k poskytování souborů s nestandardními příponami.

Obsluha souborů z více umístění

UseStaticFiles a UseFileServer ve výchozím nastavení na zprostředkovatele souborů odkazující na wwwroot. Další instance a UseFileServer mohou být poskytovány UseStaticFiles s jinými poskytovateli souborů pro obsluhu souborů z jiných umístění. Další informace najdete u tohoto problému na GitHubu.

Důležité informace o zabezpečení statických souborů

Upozorňující

UseDirectoryBrowser a UseStaticFiles může vytékat tajné kódy. Zakázání procházení adresářů v produkčním prostředí se důrazně doporučuje. Pečlivě zkontrolujte, které adresáře jsou povoleny prostřednictvím UseStaticFiles nebo UseDirectoryBrowser. Celý adresář a jeho podadresáři jsou veřejně přístupné. Ukládat soubory vhodné pro poskytování veřejnosti ve vyhrazeném adresáři, například <content_root>/wwwroot. Tyto soubory oddělte od zobrazení MVC, Razor stránek, konfiguračních souborů atd.

  • Adresy URL pro obsah vystavený obsahem UseDirectoryBrowser a UseStaticFiles podléhají omezení velikosti písmen a znaků základního systému souborů. Windows například nerozlišuje malá a velká písmena, ale macOS a Linux nejsou.

  • ASP.NET aplikace Core hostované ve službě IIS používají modul ASP.NET Core k předávání všech požadavků do aplikace, včetně požadavků na statické soubory. Obslužná rutina statického souboru služby IIS se nepoužívá a nemá šanci zpracovat požadavky.

  • Pomocí následujících kroků ve Správci služby IIS odeberte obslužnou rutinu statického souboru služby IIS na úrovni serveru nebo webu:

    1. Přejděte na funkci Moduly .
    2. V seznamu vyberte StaticFileModule .
    3. Na bočním panelu Akcí klikněte na Odebrat.

Upozorňující

Pokud je povolená obslužná rutina statického souboru služby IIS a ASP.NET základní modul je správně nakonfigurovaný, obsluhují se statické soubory. K tomu dochází například v případě, že soubor web.config není nasazený.

  • Umístěte soubory kódu, včetně .cs a .cshtml, mimo webovou kořenovou složku projektu aplikace. Logické oddělení se proto vytvoří mezi obsahem na straně klienta aplikace a serverovým kódem. Tím zabráníte úniku kódu na straně serveru.

Další materiály