Sdílet prostřednictvím


Statické soubory v ASP.NET Core

Poznámka:

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

Upozornění

Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v zásadách podpory .NET a .NET Core. Aktuální verzi tohoto článku najdete ve verzi .NET 9.

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í.

Pro aktuální vydání viz verzi .NET 9 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í přímo poskytuje 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 relativní k kořenovému adresáři webu. Š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 UseStaticFilesProgram.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 označení 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ůže přistupovat k red-rose.jpg souboru pomocí konfigurace middlewaru pro statické soubory, jak je uvedeno níže:

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 obslouží red-rose.jpg soubor.

Následující označení se vztahuje k 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 poskytování statických souborů 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. Pokud je middleware pro statický soubor zavolán před autorizačním middlewarem:

  • Na statické soubory se 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.
  • Zavolejte UseStaticFiles s uvedením cesty, po zavolá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žaduje záložní autorizační politika, aby všichni uživatelé byli autentizováni. 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 Stránky, kontrolery nebo metody akcí s [AllowAnonymous] nebo [Authorize(PolicyName="MyPolicy")] používají aplikovaný autorizační atribut místo záložní autorizační politiky.

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

Statické prostředky pod wwwroot jsou veřejně přístupné, protože výchozí middleware pro statické soubory (app.UseStaticFiles();) je voláno 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 a jakýkoliv adresář přístupný pro statické souborové middleware.

  • Obslužte je pomocí metody akce, na kterou je aplikována autorizace, a vraťte objekt FileResult:

    [Authorize]
    public class BannerImageModel : PageModel
    {
        private readonly IWebHostEnvironment _env;
    
        public BannerImageModel(IWebHostEnvironment env) =>
            _env = env;
    
        public PhysicalFileResult OnGet()
        {
            var filePath = Path.Combine(
                    _env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
    
            return PhysicalFile(filePath, "image/jpeg");
        }
    }
    

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://learn.microsoft.com/aspnet/core/mvc/models/file-uploads#upload-large-files-with-streaming
app.MapPost("/files", async (IFormFile file, LinkGenerator linker, HttpContext context) =>
    {
        // Don't rely on the file.FileName as it is only metadata that can be manipulated by the end-user
        // Take a look at the `Utilities.IsFileValid` method that takes an IFormFile and validates its signature within the AllowedFileSignatures
        
        var fileSaveName = Guid.NewGuid().ToString("N") + Path.GetExtension(file.FileName);
        await SaveFileWithCustomFileName(file, fileSaveName);
        
        context.Response.Headers.Append("Location", linker.GetPathByName(context, "GetFileByName", new { fileName = fileSaveName}));
        return TypedResults.Ok("File Uploaded Successfully!");
    })
    .RequireAuthorization("AdminsOnly");

app.Run();

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ářů

AddDirectoryBrowser př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. Chcete-li sloužit výchozí soubor z wwwroot bez toho, aby adresa URL požadavku obsahovala 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 musí být volána před UseStaticFiles pro výchozí soubor. UseDefaultFiles je přepisovač URL, který soubor nepodává.

S UseDefaultFiles žádostmi do složky wwwroot vyhledáváme:

  • 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 zavolána, pokud je hodnota vlastnosti EnableDirectoryBrowsingtrue.

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

Identifikátor URI Odpověď
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 provádějí přesměrování na straně klienta z cílového URI bez koncového / na cílový URI s koncovým /. Například z https://<hostname>/StaticFiles do https://<hostname>/StaticFiles/. Relativní adresy URL v adresáři StaticFiles jsou neplatné bez koncového lomítka (/), pokud není použita volba RedirectToAppendTrailingSlashDefaultFilesOptions.

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 pro statické soubory předá požadavek do dalšího middlewaru v řetězci. 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.

Varování

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í odkazují na zprostředkovatele souborů ukazujícího na wwwroot. Další instance UseStaticFiles a UseFileServer mohou být poskytovány s jinými poskytovateli souborů, aby obsluhovaly soubory z jiných umístění. Následující příklad volá UseStaticFiles dvakrát k obsloužení souborů 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íci značek obrázkůAppendVersion nejsou použiti, protože pomocníci značek závisí na WebRootFileProvider. WebRootFileProvider nebyla aktualizována tak, aby zahrnovala MyStaticFiles složku.

Následující kód aktualizuje WebRootFileProvider, což umožňuje pomocníku 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 vztahující se k Blazor Web Apps najdete v tématu statické soubory ASP.NET Core.

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

Varování

UseDirectoryBrowser a UseStaticFiles mohou odhalit tajemství. 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 UseDirectoryBrowser a UseStaticFiles podléhají rozlišování velkých a malých písmen a omezení znaků souborového systému. 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.

Varování

Pokud je povolená obslužná rutina statického souboru služby IIS a ASP.NET Core modul je nesprá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.
  • Ve všech prostředích kromě vývojového jsou kopie statických prostředků podávány z aktualizované složky IWebHostEnvironment.WebRootPath.

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 /:

  • Ve vývojovém prostředí vrátit wwwroot/Index.html
  • V jakémkoli prostředí kromě vývoje vraťte 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é objekty v wwwroot.

  • Nastavit "ASPNETCORE_ENVIRONMENT" v Properties/launchSettings.json na libovolnou hodnotu kromě "Development".

  • Úplně zakažte statické webové prostředky 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 na hodnotu, která není vývojová, a zaručuje, že duplicitní obsah se vrátí z wwwroot-custom místo z wwwroot.

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    // Examine Hosting environment: logging value
    EnvironmentName = Environments.Staging,
    WebRootPath = "wwwroot-custom"
});

var app = builder.Build();

app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
      Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));

app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
      app.Environment.IsDevelopment().ToString());

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

app.Run();

Další materiály

Autoři: Rick Anderson a Kirk Larkin

Statické soubory, jako jsou HTML, CSS, obrázky a JavaScript, jsou zdroje, které aplikace ASP.NET Core ve výchozím nastavení přímo poskytuje 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é cestou, která je relativní 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 UseStaticFilesProgram.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 bezparametrové UseStaticFiles označuje soubory ve webovém kořenovém adresáři jako servírovatelné. 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ůže získat přístup k souboru red-rose.jpg tím, že nakonfigurujete middleware statických souborů 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 k https://<hostname>/StaticFiles/images/red-rose.jpg obsluhuje soubor red-rose.jpg.

Následující označení se odkazují na 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é obsluhy souborů z webového kořene, 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í middleware pro statické soubory před middlewarem pro autorizaci:

  • Na statických souborech nejsou prováděny žá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:

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 záložní autorizační politika vyžaduje, aby všichni uživatelé byli ověřeni. 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 stránky, kontrolery nebo akční metody s [AllowAnonymous] nebo [Authorize(PolicyName="MyPolicy")] používají přiřazený autorizační atribut spíše než záložní autorizační zásady.

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 a jakýkoli adresář přístupný z Middleware pro statické soubory.
  • Obslužte je prostřednictvím akční metody, na kterou se vztahuje autorizace, a vraťte objekt FileResult:
[Authorize]
public class BannerImageModel : PageModel
{
    private readonly IWebHostEnvironment _env;

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

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

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

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ářů

AddDirectoryBrowser př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. Chcete-li zobrazit výchozí soubor z wwwroot bez toho, aniž by URL požadavku musel obsahovat 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 musí být zavolána před UseStaticFiles k obsluze výchozího souboru. UseDefaultFiles je přepisovač URL, který soubor neposkytuje.

Při UseDefaultFiles zasílání požadavků do složky 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án, pokud je hodnota vlastnosti true.

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

Identifikátor URI Odpověď
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é URI bez koncového / na cílovou URI s koncovým /. Například z https://<hostname>/StaticFiles do https://<hostname>/StaticFiles/. Relativní adresy URL v adresáři StaticFiles jsou neplatné bez závěrečného lomítka (/), pokud není použita možnost RedirectToAppendTrailingSlashDefaultFilesOptions.

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, statické souborové middleware předá požadavek do dalšího middlewaru v řetězci. 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.

Varování

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 jsou ve výchozím nastavení nastaveny na zprostředkovatele souborů, který odkazuje na wwwroot. Další instance UseStaticFiles a UseFileServer mohou být poskytnuty s jinými poskytovateli souborů k poskytování souborů z jiných umístění. Následující příklad volá UseStaticFiles dvakrát, aby obsloužil 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íci značek obrázkůAppendVersion se nepoužijí, protože pomocníci značek závisí na WebRootFileProvider. WebRootFileProvider nebyla aktualizována tak, aby zahrnovala MyStaticFiles složku.

Následující kód aktualizuje WebRootFileProvider, což umožňuje tagovému pomocníku pro obrázky poskytovat 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ů

Upozornění

UseDirectoryBrowser a UseStaticFiles mohou prozradit tajemství. 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ý pomocí UseDirectoryBrowser a UseStaticFiles podléhají omezeními citlivosti na velikost 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.

Varování

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 duplicitní statické prostředky obsluhují z aktualizované složky IWebHostEnvironment.WebRootPath.

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

Ve výše uvedeném kódu jsou požadavky na /:

  • Návrat ve vývojovém prostředí wwwroot/Index.html
  • V jakémkoli jiném prostředí než vývojovém vraťte 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 wwwroot.

  • Nastavit "ASPNETCORE_ENVIRONMENT" v Properties/launchSettings.json na libovolnou hodnotu jinou 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ů deaktivuje 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 na hodnotu, která není určena pro vývoj, čímž zaručuje, že duplicitní obsah bude vrácen z wwwroot-custom místo z wwwroot.

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    // Examine Hosting environment: logging value
    EnvironmentName = Environments.Staging,
    WebRootPath = "wwwroot-custom"
});

var app = builder.Build();

app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
      Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));

app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
      app.Environment.IsDevelopment().ToString());

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

app.Run();

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í přímo poskytuje 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é na základě cesty relativní 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 UseStaticFilesStartup.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 označení 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 poskytuje red-rose.jpg soubor.

Následující označení v kódu 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 obsluhy statických souborů z kořenového adresáře webu následující kód nastaví 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í statického souborového middlewaru před autorizačním middlewarem:

  • Na statické soubory nejsou prováděny žá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.
  • Zavolejte UseStaticFiles a zadejte cestu, po zavolání UseAuthorization.
  • Nastavte zásady autorizace záložního řešení.
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žaduje záložní autorizační politika, aby byli všichni uživatelé ověřeni. 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 stránky, kontrolery, nebo akční metody používají aplikovaný autorizační atribut namísto záložní autorizační politiky s [AllowAnonymous] nebo [Authorize(PolicyName="MyPolicy")].

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

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

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

  • Uložte je mimo wwwroot a jakýkoli adresář přístupný pro statické souborové middleware.
  • Obsloužíte je prostřednictvím metody akce, na kterou je aplikována autorizace, a vrátí objekt FileResult:
[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, aniž by bylo vyžadováno, aby adresa URL zahrnovala 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 musí být volána před UseStaticFiles pro odeslání výchozího souboru. UseDefaultFiles je přepisovač URL, který neslouží soubor.

S UseDefaultFiles, žádosti směrované do složky wwwroot hledají:

  • 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 spolu s předchozím kódem:

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 ukazuje Startup.Configure s 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 spolu s předchozím kódem.

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, když je hodnota vlastnosti EnableDirectoryBrowsingtrue.

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

URI Odpověď
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 provedou přesměrování na straně klienta z cílového URI bez koncového / na cílový URI s koncovým /. 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 pomocí předchozího kódu:

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 pro statické soubory předá požadavek následujícímu 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 spolu s předchozím kódem.

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.

Varování

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 se ve výchozím nastavení připojují k zprostředkovateli souborů, který ukazuje na wwwroot. Další instance UseStaticFiles a UseFileServer mohou být poskytovány 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ů

Varování

UseDirectoryBrowser a UseStaticFiles mohou prozrazovat tajemství. 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ý pomocí UseDirectoryBrowser a UseStaticFiles podléhají pravidlům citlivosti na velikost písmen a omezením 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.

Upozornění

Pokud je povolená obslužná rutina statického souboru služby IIS a ASP.NET Core modul je nesprávně nakonfigurovaný, jsou obsluhovány 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