File statik di ASP.NET Core
Catatan
Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Peringatan
Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Penting
Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Oleh Rick Anderson
File statis, seperti HTML, CSS, gambar, dan JavaScript, adalah aset aplikasi ASP.NET Core berfungsi langsung ke klien secara default.
Untuk Blazor panduan file statis, yang menambahkan atau menggantikan panduan dalam artikel ini, lihat ASP.NET File statis IntiBlazor.
Sajikan file statis
File statis disimpan dalam direktori akar web proyek. Direktori default adalah {content root}/wwwroot
, tetapi dapat diubah dengan UseWebRoot metode . Untuk informasi selengkapnya, lihat Akar konten dan akar Web.
Metode CreateBuilder ini mengatur akar konten ke direktori saat ini:
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();
File statis dapat diakses melalui jalur yang relatif terhadap akar web. Misalnya, templat proyek Aplikasi Web berisi beberapa folder dalam wwwroot
folder:
wwwroot
css
js
lib
Pertimbangkan aplikasi dengan wwwroot/images/MyImage.jpg
file . Format URI untuk mengakses file di images
folder adalah https://<hostname>/images/<image_file_name>
. Misalnya: https://localhost:5001/images/MyImage.jpg
MapStaticAssets
Membuat aplikasi web berkinerja memerlukan pengoptimalan pengiriman aset ke browser. Kemungkinan pengoptimalan meliputi:
- Layani aset tertentu sekali sampai file berubah atau browser menghapus cache-nya. Atur header ETag .
- Cegah browser menggunakan aset lama atau kedaluarsa setelah aplikasi diperbarui. Atur header Terakhir Diubah .
- Siapkan header penembolokan yang tepat.
- Gunakan middleware penembolokan.
- Menyajikan versi aset yang dikompresi jika memungkinkan.
- Gunakan CDN untuk melayani aset yang lebih dekat dengan pengguna.
- Minimalkan ukuran aset yang disajikan ke browser. Pengoptimalan ini tidak termasuk minifikasi.
MapStaticAssets adalah konvensi titik akhir perutean yang mengoptimalkan pengiriman aset statis dalam aplikasi. Ini dirancang untuk bekerja dengan semua kerangka kerja UI, termasuk Blazor, Razor Pages, dan MVC.
UseStaticFiles
juga melayani file statis, tetapi tidak memberikan tingkat pengoptimalan yang sama dengan MapStaticAssets
. Untuk perbandingan UseStaticFiles
dan MapStaticAssets
, lihat Mengoptimalkan pengiriman aset web statis .
Menyajikan file di akar web
Templat aplikasi web default memanggil MapStaticAssets metode di Program.cs
, yang memungkinkan file statis dilayani:
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();
Overload metode tanpa UseStaticFiles
parameter menandai file di akar web sebagai servable. Referensi wwwroot/images/MyImage.jpg
markup berikut :
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Dalam markup sebelumnya, karakter ~
tilde menunjuk ke akar web.
Menyajikan file di luar akar web
Pertimbangkan hierarki direktori tempat file statis untuk dilayani berada di luar akar web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Permintaan dapat mengakses red-rose.jpg
file dengan mengonfigurasi Middleware File Statis sebagai berikut:
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();
Dalam kode sebelumnya, hierarki direktori MyStaticFiles diekspos secara publik melalui segmen URI StaticFiles . Permintaan untuk https://<hostname>/StaticFiles/images/red-rose.jpg
melayani red-rose.jpg
file.
Referensi MyStaticFiles/images/red-rose.jpg
markup berikut :
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Untuk menyajikan file dari beberapa lokasi, lihat Menyajikan file dari beberapa lokasi.
Mengatur header respons HTTP
Objek StaticFileOptions dapat digunakan untuk mengatur header respons HTTP. Selain mengonfigurasi penyajian file statis dari akar web, kode berikut mengatur header 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();
Kode sebelumnya membuat file statis tersedia untuk umum di cache lokal selama satu minggu.
Otorisasi file statis
Templat ASP.NET Core memanggil MapStaticAssets sebelum memanggil UseAuthorization. Sebagian besar aplikasi mengikuti pola ini. Ketika Middleware File Statis dipanggil sebelum middleware otorisasi:
- Tidak ada pemeriksaan otorisasi yang dilakukan pada file statis.
- File statis yang dilayani oleh Middleware File Statis, seperti file di bawah
wwwroot
, dapat diakses secara publik.
Untuk menyajikan file statis berdasarkan otorisasi:
- Simpan di luar
wwwroot
. - Panggil
UseStaticFiles
, menentukan jalur, setelah memanggilUseAuthorization
. - Atur kebijakan otorisasi fallback.
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();
Dalam kode sebelumnya, kebijakan otorisasi fallback mengharuskan semua pengguna diautentikasi. Titik akhir seperti pengontrol, Razor Halaman, dll yang menentukan persyaratan otorisasi mereka sendiri tidak menggunakan kebijakan otorisasi fallback. Misalnya, Razor Halaman, pengontrol, atau metode tindakan dengan [AllowAnonymous]
atau [Authorize(PolicyName="MyPolicy")]
menggunakan atribut otorisasi yang diterapkan daripada kebijakan otorisasi fallback.
RequireAuthenticatedUser menambahkan ke instans DenyAnonymousAuthorizationRequirement saat ini, yang memberlakukan bahwa pengguna saat ini diautentikasi.
Aset statis di bawah wwwroot
dapat diakses secara publik karena Middleware File Statis default (app.UseStaticFiles();
) dipanggil sebelum UseAuthentication
. Aset statis di folder MyStaticFiles memerlukan autentikasi. Kode sampel menunjukkan ini.
Pendekatan alternatif untuk melayani file berdasarkan otorisasi adalah dengan:
Simpan di luar
wwwroot
dan direktori apa pun yang dapat diakses oleh Middleware File Statis.Sajikan melalui metode tindakan tempat otorisasi diterapkan dan mengembalikan FileResult objek:
[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"); } }
Pendekatan sebelumnya memerlukan halaman atau titik akhir per file. Kode berikut mengembalikan file atau mengunggah file untuk pengguna terautentikasi:
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 dalam sampel sebelumnya menggunakan buffer memori untuk diunggah. Untuk menangani streaming penggunaan file besar. Lihat Mengunggah file besar dengan streaming.
Lihat folder StaticFileAuth GitHub untuk sampel lengkapnya.
Penjelajahan direktori
Penjelajahan direktori memungkinkan daftar direktori dalam direktori tertentu.
Penjelajahan direktori dinonaktifkan secara default karena alasan keamanan. Untuk informasi selengkapnya, lihat Pertimbangan keamanan untuk file statis.
Aktifkan penjelajahan direktori dengan AddDirectoryBrowser dan 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();
Kode sebelumnya memungkinkan penjelajahan direktori folder wwwroot/images menggunakan URL https://<hostname>/MyImages
, dengan tautan ke setiap file dan folder:
AddDirectoryBrowser
menambahkan layanan yang diperlukan oleh middleware penjelajahan direktori, termasuk HtmlEncoder. Layanan ini dapat ditambahkan oleh panggilan lain, seperti AddRazorPages, tetapi sebaiknya panggil AddDirectoryBrowser
untuk memastikan layanan ditambahkan di semua aplikasi.
Melayani dokumen default
Mengatur halaman default memberi pengunjung titik awal di situs. Untuk melayani file default dari wwwroot
tanpa memerlukan URL permintaan untuk menyertakan nama file, panggil UseDefaultFiles metode :
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
harus dipanggil sebelumnya UseStaticFiles
untuk melayani file default. UseDefaultFiles
adalah penulis ulang URL yang tidak melayani file.
Dengan UseDefaultFiles
, permintaan ke folder untuk wwwroot
mencari:
default.htm
default.html
index.htm
index.html
File pertama yang ditemukan dari daftar dilayani seolah-olah permintaan menyertakan nama file. URL browser terus mencerminkan URI yang diminta. Misalnya, di aplikasi sampel, permintaan untuk https://localhost:<port>/def/
dilayani default.html
dari wwwroot/def
.
Kode berikut mengubah nama file default menjadi 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 untuk dokumen default
UseFileServer menggabungkan fungsionalitas UseStaticFiles
, UseDefaultFiles
, dan secara UseDirectoryBrowser
opsional .
Panggil app.UseFileServer
untuk mengaktifkan penyajian file statis dan file default. Penjelajahan direktori tidak diaktifkan:
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();
Kode berikut memungkinkan penyajian file statis, file default, dan penjelajahan direktori:
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();
Pertimbangkan hierarki direktori berikut:
wwwroot
css
images
js
MyStaticFiles
defaultFiles
default.html
image3.png
images
MyImage.jpg
Kode berikut memungkinkan penyajian file statis, file default, dan penjelajahan direktori dari MyStaticFiles
:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
AddDirectoryBrowser harus dipanggil ketika EnableDirectoryBrowsing
nilai properti adalah true
.
Menggunakan hierarki dan kode file sebelumnya, URL diselesaikan sebagai berikut:
URI | Respons |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
daftar direktori |
https://<hostname>/StaticFiles/defaultFiles |
MyStaticFiles/defaultFiles/default.html |
https://<hostname>/StaticFiles/defaultFiles/image3.png |
MyStaticFiles/defaultFiles//image3.png |
Jika tidak ada file bernama default di direktori MyStaticFiles, https://<hostname>/StaticFiles
mengembalikan daftar direktori dengan tautan yang dapat diklik:
UseDefaultFiles dan UseDirectoryBrowser lakukan pengalihan sisi klien dari URI target tanpa mengikuti /
URI target dengan trailing /
. Misalnya, dari https://<hostname>/StaticFiles
ke https://<hostname>/StaticFiles/
. URL relatif dalam direktori StaticFiles tidak valid tanpa garis miring berikutnya (/
) kecuali RedirectToAppendTrailingSlash opsi DefaultFilesOptions digunakan.
FileExtensionContentTypeProvider
Kelas FileExtensionContentTypeProvider berisi properti Pemetaan yang berfungsi sebagai pemetaan ekstensi file ke jenis konten MIME. Dalam sampel berikut, beberapa ekstensi file dipetakan ke jenis MIME yang diketahui. Ekstensi .rtf diganti, dan .mp4 dihapus:
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();
Lihat Jenis konten MIME.
Jenis konten non-standar
Middleware File Statis memahami hampir 400 jenis konten file yang diketahui. Jika pengguna meminta file dengan jenis file yang tidak diketahui, Middleware File Statis meneruskan permintaan ke middleware berikutnya dalam alur. Jika tidak ada middleware yang menangani permintaan, respons 404 Tidak Ditemukan dikembalikan. Jika penjelajahan direktori diaktifkan, tautan ke file ditampilkan dalam daftar direktori.
Kode berikut memungkinkan penyajian jenis yang tidak diketahui dan merender file yang tidak diketahui sebagai gambar:
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();
Dengan kode sebelumnya, permintaan untuk file dengan jenis konten yang tidak diketahui dikembalikan sebagai gambar.
Peringatan
Mengaktifkan ServeUnknownFileTypes adalah risiko keamanan. Ini dinonaktifkan secara default, dan penggunaannya tidak disarankan. FileExtensionContentTypeProvider menyediakan alternatif yang lebih aman untuk melayani file dengan ekstensi non-standar.
Menyajikan file dari beberapa lokasi
Pertimbangkan halaman berikut Razor yang menampilkan /MyStaticFiles/image3.png
file:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
dan UseFileServer
default ke penyedia file yang menunjuk ke wwwroot
. Instans tambahan dan UseStaticFiles
UseFileServer
dapat disediakan dengan penyedia file lain untuk melayani file dari lokasi lain. Contoh berikut memanggil UseStaticFiles
dua kali untuk melayani file dari dan wwwroot
MyStaticFiles
:
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Menggunakan kode sebelumnya:
- File
/MyStaticFiles/image3.png
ditampilkan. - Pembantu AppendVersion Tag Gambar tidak diterapkan karena Pembantu Tag bergantung pada WebRootFileProvider.
WebRootFileProvider
belum diperbarui untuk menyertakanMyStaticFiles
folder.
Kode berikut memperbarui WebRootFileProvider
, yang memungkinkan Pembantu Tag Gambar untuk menyediakan versi:
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();
Catatan
Pendekatan sebelumnya berlaku untuk Razor aplikasi Pages dan MVC. Untuk panduan yang berlaku untuk Blazor Web Apps, lihat file statis ASP.NET CoreBlazor.
Pertimbangan keamanan untuk file statis
Peringatan
UseDirectoryBrowser
dan UseStaticFiles
dapat membocorkan rahasia. Menonaktifkan penjelajahan direktori dalam produksi sangat disarankan. Tinjau direktori mana yang diaktifkan dengan hati-hati melalui UseStaticFiles
atau UseDirectoryBrowser
. Seluruh direktori dan sub-direktorinya dapat diakses secara publik. Simpan file yang cocok untuk dilayani ke publik di direktori khusus, seperti <content_root>/wwwroot
. Pisahkan file-file ini dari tampilan MVC, Razor Halaman, file konfigurasi, dll.
URL untuk konten yang diekspos dengan
UseDirectoryBrowser
,UseStaticFiles
, danMapStaticAssets
tunduk pada sensitivitas kasus dan pembatasan karakter dari sistem file yang mendasar. Misalnya, Windows tidak peka huruf besar/kecil, tetapi macOS dan Linux tidak.ASP.NET aplikasi Core yang dihosting di IIS menggunakan Modul Inti ASP.NET untuk meneruskan semua permintaan ke aplikasi, termasuk permintaan file statis. Handler file statis IIS tidak digunakan dan tidak memiliki kesempatan untuk menangani permintaan.
Selesaikan langkah-langkah berikut di Manajer IIS untuk menghapus handler file statis IIS di tingkat server atau situs web:
- Navigasi ke fitur Modul .
- Pilih StaticFileModule dalam daftar.
- Klik Hapus di bilah samping Tindakan .
Peringatan
Jika handler file statis IIS diaktifkan dan ASP.NET Core Module dikonfigurasi dengan salah, file statis dilayani. Ini terjadi, misalnya, jika file web.config tidak disebarkan.
- Tempatkan file kode, termasuk
.cs
dan.cshtml
, di luar akar web proyek aplikasi. Oleh karena itu, pemisahan logis dibuat antara konten sisi klien aplikasi dan kode berbasis server. Ini mencegah kode sisi server bocor.
Melayani file di luar wwwroot dengan memperbarui IWebHostEnvironment.WebRootPath
Kapan IWebHostEnvironment.WebRootPath diatur ke folder selain wwwroot
:
- Di lingkungan pengembangan, aset statis yang ditemukan di keduanya
wwwroot
dan yang diperbaruiIWebHostEnvironment.WebRootPath
disajikan dariwwwroot
. - Di lingkungan apa pun selain pengembangan, aset statis duplikat disajikan dari folder yang diperbarui
IWebHostEnvironment.WebRootPath
.
Pertimbangkan aplikasi web yang dibuat dengan templat web kosong:
Berisi
Index.html
file diwwwroot
danwwwroot-custom
.Dengan file yang diperbarui
Program.cs
berikut yang menetapkanWebRootPath = "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();
Dalam kode sebelumnya, permintaan ke /
:
- Dalam pengembalian lingkungan pengembangan
wwwroot/Index.html
- Di lingkungan apa pun selain pengembalian pengembangan
wwwroot-custom/Index.html
Untuk memastikan aset dari wwwroot-custom
dikembalikan, gunakan salah satu pendekatan berikut:
Hapus aset bernama duplikat di
wwwroot
.Atur
"ASPNETCORE_ENVIRONMENT"
ke nilai apa pun selain"Development"
.Properties/launchSettings.json
Nonaktifkan aset web statis sepenuhnya dengan mengatur
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
dalam file proyek. PERINGATAN, menonaktifkan aset web statis menonaktifkan Razor Pustaka Kelas.Tambahkan XML berikut ke file proyek:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
Kode berikut diperbarui IWebHostEnvironment.WebRootPath
ke nilai non pengembangan, menjamin konten duplikat dikembalikan dari wwwroot-custom
bukan wwwroot
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Examine Hosting environment: logging value
EnvironmentName = Environments.Staging,
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
app.Environment.IsDevelopment().ToString());
app.UseDefaultFiles();
app.MapStaticAssets();
app.Run();
Sumber Daya Tambahan:
Oleh Rick Anderson
File statis, seperti HTML, CSS, gambar, dan JavaScript, adalah aset aplikasi ASP.NET Core berfungsi langsung ke klien secara default.
Sajikan file statis
File statis disimpan dalam direktori akar web proyek. Direktori default adalah {content root}/wwwroot
, tetapi dapat diubah dengan UseWebRoot metode . Untuk informasi selengkapnya, lihat Akar konten dan akar Web.
Metode CreateBuilder ini mengatur akar konten ke direktori saat ini:
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();
File statis dapat diakses melalui jalur yang relatif terhadap akar web. Misalnya, templat proyek Aplikasi Web berisi beberapa folder dalam wwwroot
folder:
wwwroot
css
js
lib
Pertimbangkan untuk membuat folder wwwroot/images dan menambahkan wwwroot/images/MyImage.jpg
file. Format URI untuk mengakses file di images
folder adalah https://<hostname>/images/<image_file_name>
. Misalnya: https://localhost:5001/images/MyImage.jpg
Menyajikan file di akar web
Templat aplikasi web default memanggil UseStaticFiles metode di Program.cs
, yang memungkinkan file statis dilayani:
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();
Overload metode tanpa UseStaticFiles
parameter menandai file di akar web sebagai servable. Referensi wwwroot/images/MyImage.jpg
markup berikut :
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Dalam markup sebelumnya, karakter ~
tilde menunjuk ke akar web.
Menyajikan file di luar akar web
Pertimbangkan hierarki direktori tempat file statis untuk dilayani berada di luar akar web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Permintaan dapat mengakses red-rose.jpg
file dengan mengonfigurasi Middleware File Statis sebagai berikut:
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();
Dalam kode sebelumnya, hierarki direktori MyStaticFiles diekspos secara publik melalui segmen URI StaticFiles . Permintaan untuk https://<hostname>/StaticFiles/images/red-rose.jpg
melayani red-rose.jpg
file.
Referensi MyStaticFiles/images/red-rose.jpg
markup berikut :
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Untuk menyajikan file dari beberapa lokasi, lihat Menyajikan file dari beberapa lokasi.
Mengatur header respons HTTP
Objek StaticFileOptions dapat digunakan untuk mengatur header respons HTTP. Selain mengonfigurasi penyajian file statis dari akar web, kode berikut mengatur header 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();
Kode sebelumnya membuat file statis tersedia untuk umum di cache lokal selama satu minggu (604800 detik).
Otorisasi file statis
Templat ASP.NET Core memanggil UseStaticFiles sebelum memanggil UseAuthorization. Sebagian besar aplikasi mengikuti pola ini. Ketika Middleware File Statis dipanggil sebelum middleware otorisasi:
- Tidak ada pemeriksaan otorisasi yang dilakukan pada file statis.
- File statis yang dilayani oleh Middleware File Statis, seperti file di bawah
wwwroot
, dapat diakses secara publik.
Untuk menyajikan file statis berdasarkan otorisasi:
- Simpan di luar
wwwroot
. - Panggil
UseStaticFiles
, menentukan jalur, setelah memanggilUseAuthorization
. - Atur kebijakan otorisasi fallback.
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();
Dalam kode sebelumnya, kebijakan otorisasi fallback mengharuskan semua pengguna diautentikasi. Titik akhir seperti pengontrol, Razor Halaman, dll yang menentukan persyaratan otorisasi mereka sendiri tidak menggunakan kebijakan otorisasi fallback. Misalnya, Razor Halaman, pengontrol, atau metode tindakan dengan [AllowAnonymous]
atau [Authorize(PolicyName="MyPolicy")]
menggunakan atribut otorisasi yang diterapkan daripada kebijakan otorisasi fallback.
RequireAuthenticatedUser menambahkan ke instans DenyAnonymousAuthorizationRequirement saat ini, yang memberlakukan bahwa pengguna saat ini diautentikasi.
Aset statis di bawah wwwroot
dapat diakses secara publik karena Middleware File Statis default (app.UseStaticFiles();
) dipanggil sebelum UseAuthentication
. Aset statis di folder MyStaticFiles memerlukan autentikasi. Kode sampel menunjukkan ini.
Pendekatan alternatif untuk melayani file berdasarkan otorisasi adalah dengan:
Simpan di luar
wwwroot
dan direktori apa pun yang dapat diakses oleh Middleware File Statis.Sajikan melalui metode tindakan tempat otorisasi diterapkan dan mengembalikan FileResult objek:
[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"); } }
Pendekatan sebelumnya memerlukan halaman atau titik akhir per file. Kode berikut mengembalikan file atau mengunggah file untuk pengguna terautentikasi:
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();
Lihat folder StaticFileAuth GitHub untuk sampel lengkapnya.
Penjelajahan direktori
Penjelajahan direktori memungkinkan daftar direktori dalam direktori tertentu.
Penjelajahan direktori dinonaktifkan secara default karena alasan keamanan. Untuk informasi selengkapnya, lihat Pertimbangan keamanan untuk file statis.
Aktifkan penjelajahan direktori dengan AddDirectoryBrowser dan 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();
Kode sebelumnya memungkinkan penjelajahan direktori folder wwwroot/images menggunakan URL https://<hostname>/MyImages
, dengan tautan ke setiap file dan folder:
AddDirectoryBrowser
menambahkan layanan yang diperlukan oleh middleware penjelajahan direktori, termasuk HtmlEncoder. Layanan ini dapat ditambahkan oleh panggilan lain, seperti AddRazorPages, tetapi sebaiknya panggil AddDirectoryBrowser
untuk memastikan layanan ditambahkan di semua aplikasi.
Melayani dokumen default
Mengatur halaman default memberi pengunjung titik awal di situs. Untuk melayani file default dari wwwroot
tanpa memerlukan URL permintaan untuk menyertakan nama file, panggil UseDefaultFiles metode :
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
harus dipanggil sebelumnya UseStaticFiles
untuk melayani file default. UseDefaultFiles
adalah penulis ulang URL yang tidak melayani file.
Dengan UseDefaultFiles
, permintaan ke folder untuk wwwroot
mencari:
default.htm
default.html
index.htm
index.html
File pertama yang ditemukan dari daftar dilayani seolah-olah permintaan menyertakan nama file. URL browser terus mencerminkan URI yang diminta.
Kode berikut mengubah nama file default menjadi 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 untuk dokumen default
UseFileServer menggabungkan fungsionalitas UseStaticFiles
, UseDefaultFiles
, dan secara UseDirectoryBrowser
opsional .
Panggil app.UseFileServer
untuk mengaktifkan penyajian file statis dan file default. Penjelajahan direktori tidak diaktifkan:
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();
Kode berikut memungkinkan penyajian file statis, file default, dan penjelajahan direktori:
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();
Pertimbangkan hierarki direktori berikut:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
Kode berikut memungkinkan penyajian file statis, file default, dan penjelajahan direktori dari MyStaticFiles
:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
AddDirectoryBrowser harus dipanggil ketika EnableDirectoryBrowsing
nilai properti adalah true
.
Menggunakan hierarki dan kode file sebelumnya, URL diselesaikan sebagai berikut:
URI | Respons |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Jika tidak ada file bernama default di direktori MyStaticFiles, https://<hostname>/StaticFiles
mengembalikan daftar direktori dengan tautan yang dapat diklik:
UseDefaultFiles dan UseDirectoryBrowser lakukan pengalihan sisi klien dari URI target tanpa mengikuti /
URI target dengan trailing /
. Misalnya, dari https://<hostname>/StaticFiles
ke https://<hostname>/StaticFiles/
. URL relatif dalam direktori StaticFiles tidak valid tanpa garis miring berikutnya (/
) kecuali RedirectToAppendTrailingSlash opsi DefaultFilesOptions digunakan.
FileExtensionContentTypeProvider
Kelas FileExtensionContentTypeProvider berisi Mappings
properti yang berfungsi sebagai pemetaan ekstensi file ke jenis konten MIME. Dalam sampel berikut, beberapa ekstensi file dipetakan ke jenis MIME yang diketahui. Ekstensi .rtf diganti, dan .mp4 dihapus:
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();
Lihat Jenis konten MIME.
Jenis konten non-standar
Middleware File Statis memahami hampir 400 jenis konten file yang diketahui. Jika pengguna meminta file dengan jenis file yang tidak diketahui, Middleware File Statis meneruskan permintaan ke middleware berikutnya dalam alur. Jika tidak ada middleware yang menangani permintaan, respons 404 Tidak Ditemukan dikembalikan. Jika penjelajahan direktori diaktifkan, tautan ke file ditampilkan dalam daftar direktori.
Kode berikut memungkinkan penyajian jenis yang tidak diketahui dan merender file yang tidak diketahui sebagai gambar:
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();
Dengan kode sebelumnya, permintaan untuk file dengan jenis konten yang tidak diketahui dikembalikan sebagai gambar.
Peringatan
Mengaktifkan ServeUnknownFileTypes adalah risiko keamanan. Ini dinonaktifkan secara default, dan penggunaannya tidak disarankan. FileExtensionContentTypeProvider menyediakan alternatif yang lebih aman untuk melayani file dengan ekstensi non-standar.
Menyajikan file dari beberapa lokasi
Pertimbangkan halaman berikut Razor yang menampilkan /MyStaticFiles/image3.png
file:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
dan UseFileServer
default ke penyedia file yang menunjuk ke wwwroot
. Instans tambahan dan UseStaticFiles
UseFileServer
dapat disediakan dengan penyedia file lain untuk melayani file dari lokasi lain. Contoh berikut memanggil UseStaticFiles
dua kali untuk melayani file dari dan wwwroot
MyStaticFiles
:
app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Menggunakan kode sebelumnya:
- File
/MyStaticFiles/image3.png
ditampilkan. - Pembantu AppendVersion Tag Gambar tidak diterapkan karena Pembantu Tag bergantung pada WebRootFileProvider.
WebRootFileProvider
belum diperbarui untuk menyertakanMyStaticFiles
folder.
Kode berikut memperbarui WebRootFileProvider
, yang memungkinkan Pembantu Tag Gambar untuk menyediakan versi:
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();
Catatan
Pendekatan sebelumnya berlaku untuk Razor aplikasi Pages dan MVC. Untuk panduan yang berlaku untuk Blazor Web Apps, lihat file statis ASP.NET CoreBlazor.
Pertimbangan keamanan untuk file statis
Peringatan
UseDirectoryBrowser
dan UseStaticFiles
dapat membocorkan rahasia. Menonaktifkan penjelajahan direktori dalam produksi sangat disarankan. Tinjau direktori mana yang diaktifkan dengan hati-hati melalui UseStaticFiles
atau UseDirectoryBrowser
. Seluruh direktori dan sub-direktorinya dapat diakses secara publik. Simpan file yang cocok untuk dilayani ke publik di direktori khusus, seperti <content_root>/wwwroot
. Pisahkan file-file ini dari tampilan MVC, Razor Halaman, file konfigurasi, dll.
URL untuk konten yang diekspos dengan
UseDirectoryBrowser
danUseStaticFiles
tunduk pada sensitivitas kasus dan pembatasan karakter dari sistem file yang mendasar. Misalnya, Windows tidak peka huruf besar/kecil, tetapi macOS dan Linux tidak.ASP.NET aplikasi Core yang dihosting di IIS menggunakan Modul Inti ASP.NET untuk meneruskan semua permintaan ke aplikasi, termasuk permintaan file statis. Handler file statis IIS tidak digunakan dan tidak memiliki kesempatan untuk menangani permintaan.
Selesaikan langkah-langkah berikut di Manajer IIS untuk menghapus handler file statis IIS di tingkat server atau situs web:
- Navigasi ke fitur Modul .
- Pilih StaticFileModule dalam daftar.
- Klik Hapus di bilah samping Tindakan .
Peringatan
Jika handler file statis IIS diaktifkan dan ASP.NET Core Module dikonfigurasi dengan salah, file statis dilayani. Ini terjadi, misalnya, jika file web.config tidak disebarkan.
- Tempatkan file kode, termasuk
.cs
dan.cshtml
, di luar akar web proyek aplikasi. Oleh karena itu, pemisahan logis dibuat antara konten sisi klien aplikasi dan kode berbasis server. Ini mencegah kode sisi server bocor.
Melayani file di luar wwwroot dengan memperbarui IWebHostEnvironment.WebRootPath
Kapan IWebHostEnvironment.WebRootPath diatur ke folder selain wwwroot
:
- Di lingkungan pengembangan, aset statis yang ditemukan di keduanya
wwwroot
dan yang diperbaruiIWebHostEnvironment.WebRootPath
disajikan dariwwwroot
. - Di lingkungan apa pun selain pengembangan, aset statis duplikat disajikan dari folder yang diperbarui
IWebHostEnvironment.WebRootPath
.
Pertimbangkan aplikasi web yang dibuat dengan templat web kosong:
Berisi
Index.html
file diwwwroot
danwwwroot-custom
.Dengan file yang diperbarui
Program.cs
berikut yang menetapkanWebRootPath = "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();
Dalam kode sebelumnya, permintaan ke /
:
- Dalam pengembalian lingkungan pengembangan
wwwroot/Index.html
- Di lingkungan apa pun selain pengembalian pengembangan
wwwroot-custom/Index.html
Untuk memastikan aset dari wwwroot-custom
dikembalikan, gunakan salah satu pendekatan berikut:
Hapus aset bernama duplikat di
wwwroot
.Atur
"ASPNETCORE_ENVIRONMENT"
ke nilai apa pun selain"Development"
.Properties/launchSettings.json
Nonaktifkan aset web statis sepenuhnya dengan mengatur
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
dalam file proyek. PERINGATAN, menonaktifkan aset web statis menonaktifkan Razor Pustaka Kelas.Tambahkan JSON berikut ke file proyek:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
Kode berikut diperbarui IWebHostEnvironment.WebRootPath
ke nilai non pengembangan, menjamin konten duplikat dikembalikan dari wwwroot-custom
bukan 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();
Sumber Daya Tambahan:
Oleh Rick Anderson dan Kirk Larkin
File statis, seperti HTML, CSS, gambar, dan JavaScript, adalah aset aplikasi ASP.NET Core berfungsi langsung ke klien secara default.
Sajikan file statis
File statis disimpan dalam direktori akar web proyek. Direktori default adalah {content root}/wwwroot
, tetapi dapat diubah dengan UseWebRoot metode . Untuk informasi selengkapnya, lihat Akar konten dan akar Web.
Metode CreateBuilder ini mengatur akar konten ke direktori saat ini:
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();
File statis dapat diakses melalui jalur yang relatif terhadap akar web. Misalnya, templat proyek Aplikasi Web berisi beberapa folder dalam wwwroot
folder:
wwwroot
css
js
lib
Pertimbangkan untuk membuat folder wwwroot/images dan menambahkan wwwroot/images/MyImage.jpg
file. Format URI untuk mengakses file di images
folder adalah https://<hostname>/images/<image_file_name>
. Misalnya: https://localhost:5001/images/MyImage.jpg
Menyajikan file di akar web
Templat aplikasi web default memanggil UseStaticFiles metode di Program.cs
, yang memungkinkan file statis dilayani:
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();
Overload metode tanpa UseStaticFiles
parameter menandai file di akar web sebagai servable. Referensi wwwroot/images/MyImage.jpg
markup berikut :
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Dalam markup sebelumnya, karakter ~
tilde menunjuk ke akar web.
Menyajikan file di luar akar web
Pertimbangkan hierarki direktori tempat file statis untuk dilayani berada di luar akar web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Permintaan dapat mengakses red-rose.jpg
file dengan mengonfigurasi Middleware File Statis sebagai berikut:
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();
Dalam kode sebelumnya, hierarki direktori MyStaticFiles diekspos secara publik melalui segmen URI StaticFiles . Permintaan untuk https://<hostname>/StaticFiles/images/red-rose.jpg
melayani red-rose.jpg
file.
Referensi MyStaticFiles/images/red-rose.jpg
markup berikut :
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Untuk menyajikan file dari beberapa lokasi, lihat Menyajikan file dari beberapa lokasi.
Mengatur header respons HTTP
Objek StaticFileOptions dapat digunakan untuk mengatur header respons HTTP. Selain mengonfigurasi penyajian file statis dari akar web, kode berikut mengatur header 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();
Kode sebelumnya membuat file statis tersedia untuk umum di cache lokal selama satu minggu (604800 detik).
Otorisasi file statis
Templat ASP.NET Core memanggil UseStaticFiles sebelum memanggil UseAuthorization. Sebagian besar aplikasi mengikuti pola ini. Ketika Middleware File Statis dipanggil sebelum middleware otorisasi:
- Tidak ada pemeriksaan otorisasi yang dilakukan pada file statis.
- File statis yang dilayani oleh Middleware File Statis, seperti file di bawah
wwwroot
, dapat diakses secara publik.
Untuk menyajikan file statis berdasarkan otorisasi:
- Simpan di luar
wwwroot
. - Panggil
UseStaticFiles
, menentukan jalur, setelah memanggilUseAuthorization
. - Atur kebijakan otorisasi fallback.
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();
Dalam kode sebelumnya, kebijakan otorisasi fallback mengharuskan semua pengguna diautentikasi. Titik akhir seperti pengontrol, Razor Halaman, dll yang menentukan persyaratan otorisasi mereka sendiri tidak menggunakan kebijakan otorisasi fallback. Misalnya, Razor Halaman, pengontrol, atau metode tindakan dengan [AllowAnonymous]
atau [Authorize(PolicyName="MyPolicy")]
menggunakan atribut otorisasi yang diterapkan daripada kebijakan otorisasi fallback.
RequireAuthenticatedUser menambahkan ke instans DenyAnonymousAuthorizationRequirement saat ini, yang memberlakukan bahwa pengguna saat ini diautentikasi.
Aset statis di bawah wwwroot
dapat diakses secara publik karena Middleware File Statis default (app.UseStaticFiles();
) dipanggil sebelum UseAuthentication
. Aset statis di folder MyStaticFiles memerlukan autentikasi. Kode sampel menunjukkan ini.
Pendekatan alternatif untuk melayani file berdasarkan otorisasi adalah dengan:
- Simpan di luar
wwwroot
dan direktori apa pun yang dapat diakses oleh Middleware File Statis. - Sajikan melalui metode tindakan tempat otorisasi diterapkan dan mengembalikan FileResult objek:
[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");
}
}
Penjelajahan direktori
Penjelajahan direktori memungkinkan daftar direktori dalam direktori tertentu.
Penjelajahan direktori dinonaktifkan secara default karena alasan keamanan. Untuk informasi selengkapnya, lihat Pertimbangan keamanan untuk file statis.
Aktifkan penjelajahan direktori dengan AddDirectoryBrowser dan 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();
Kode sebelumnya memungkinkan penjelajahan direktori folder wwwroot/images menggunakan URL https://<hostname>/MyImages
, dengan tautan ke setiap file dan folder:
AddDirectoryBrowser
menambahkan layanan yang diperlukan oleh middleware penjelajahan direktori, termasuk HtmlEncoder. Layanan ini dapat ditambahkan oleh panggilan lain, seperti AddRazorPages, tetapi sebaiknya panggil AddDirectoryBrowser
untuk memastikan layanan ditambahkan di semua aplikasi.
Melayani dokumen default
Mengatur halaman default memberi pengunjung titik awal di situs. Untuk melayani file default dari wwwroot
tanpa memerlukan URL permintaan untuk menyertakan nama file, panggil UseDefaultFiles metode :
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
harus dipanggil sebelumnya UseStaticFiles
untuk melayani file default. UseDefaultFiles
adalah penulis ulang URL yang tidak melayani file.
Dengan UseDefaultFiles
, permintaan ke folder untuk wwwroot
mencari:
default.htm
default.html
index.htm
index.html
File pertama yang ditemukan dari daftar dilayani seolah-olah permintaan menyertakan nama file. URL browser terus mencerminkan URI yang diminta.
Kode berikut mengubah nama file default menjadi 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 untuk dokumen default
UseFileServer menggabungkan fungsionalitas UseStaticFiles
, UseDefaultFiles
, dan secara UseDirectoryBrowser
opsional .
Panggil app.UseFileServer
untuk mengaktifkan penyajian file statis dan file default. Penjelajahan direktori tidak diaktifkan:
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();
Kode berikut memungkinkan penyajian file statis, file default, dan penjelajahan direktori:
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();
Pertimbangkan hierarki direktori berikut:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
Kode berikut memungkinkan penyajian file statis, file default, dan penjelajahan direktori dari MyStaticFiles
:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
AddDirectoryBrowser harus dipanggil ketika EnableDirectoryBrowsing
nilai properti adalah true
.
Menggunakan hierarki dan kode file sebelumnya, URL diselesaikan sebagai berikut:
URI | Respons |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Jika tidak ada file bernama default di direktori MyStaticFiles, https://<hostname>/StaticFiles
mengembalikan daftar direktori dengan tautan yang dapat diklik:
UseDefaultFiles dan UseDirectoryBrowser lakukan pengalihan sisi klien dari URI target tanpa mengikuti /
URI target dengan trailing /
. Misalnya, dari https://<hostname>/StaticFiles
ke https://<hostname>/StaticFiles/
. URL relatif dalam direktori StaticFiles tidak valid tanpa garis miring berikutnya (/
) kecuali RedirectToAppendTrailingSlash opsi DefaultFilesOptions digunakan.
FileExtensionContentTypeProvider
Kelas FileExtensionContentTypeProvider berisi Mappings
properti yang berfungsi sebagai pemetaan ekstensi file ke jenis konten MIME. Dalam sampel berikut, beberapa ekstensi file dipetakan ke jenis MIME yang diketahui. Ekstensi .rtf diganti, dan .mp4 dihapus:
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();
Lihat Jenis konten MIME.
Jenis konten non-standar
Middleware File Statis memahami hampir 400 jenis konten file yang diketahui. Jika pengguna meminta file dengan jenis file yang tidak diketahui, Middleware File Statis meneruskan permintaan ke middleware berikutnya dalam alur. Jika tidak ada middleware yang menangani permintaan, respons 404 Tidak Ditemukan dikembalikan. Jika penjelajahan direktori diaktifkan, tautan ke file ditampilkan dalam daftar direktori.
Kode berikut memungkinkan penyajian jenis yang tidak diketahui dan merender file yang tidak diketahui sebagai gambar:
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();
Dengan kode sebelumnya, permintaan untuk file dengan jenis konten yang tidak diketahui dikembalikan sebagai gambar.
Peringatan
Mengaktifkan ServeUnknownFileTypes adalah risiko keamanan. Ini dinonaktifkan secara default, dan penggunaannya tidak disarankan. FileExtensionContentTypeProvider menyediakan alternatif yang lebih aman untuk melayani file dengan ekstensi non-standar.
Menyajikan file dari beberapa lokasi
Pertimbangkan halaman berikut Razor yang menampilkan /MyStaticFiles/image3.png
file:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
dan UseFileServer
default ke penyedia file yang menunjuk ke wwwroot
. Instans tambahan dan UseStaticFiles
UseFileServer
dapat disediakan dengan penyedia file lain untuk melayani file dari lokasi lain. Contoh berikut memanggil UseStaticFiles
dua kali untuk melayani file dari dan wwwroot
MyStaticFiles
:
app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Menggunakan kode sebelumnya:
- File
/MyStaticFiles/image3.png
ditampilkan. - Pembantu AppendVersion Tag Gambar tidak diterapkan karena Pembantu Tag bergantung pada WebRootFileProvider.
WebRootFileProvider
belum diperbarui untuk menyertakanMyStaticFiles
folder.
Kode berikut memperbarui WebRootFileProvider
, yang memungkinkan Pembantu Tag Gambar untuk menyediakan versi:
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();
Pertimbangan keamanan untuk file statis
Peringatan
UseDirectoryBrowser
dan UseStaticFiles
dapat membocorkan rahasia. Menonaktifkan penjelajahan direktori dalam produksi sangat disarankan. Tinjau direktori mana yang diaktifkan dengan hati-hati melalui UseStaticFiles
atau UseDirectoryBrowser
. Seluruh direktori dan sub-direktorinya dapat diakses secara publik. Simpan file yang cocok untuk dilayani ke publik di direktori khusus, seperti <content_root>/wwwroot
. Pisahkan file-file ini dari tampilan MVC, Razor Halaman, file konfigurasi, dll.
URL untuk konten yang diekspos dengan
UseDirectoryBrowser
danUseStaticFiles
tunduk pada sensitivitas kasus dan pembatasan karakter dari sistem file yang mendasar. Misalnya, Windows tidak peka huruf besar/kecil, tetapi macOS dan Linux tidak.ASP.NET aplikasi Core yang dihosting di IIS menggunakan Modul Inti ASP.NET untuk meneruskan semua permintaan ke aplikasi, termasuk permintaan file statis. Handler file statis IIS tidak digunakan dan tidak memiliki kesempatan untuk menangani permintaan.
Selesaikan langkah-langkah berikut di Manajer IIS untuk menghapus handler file statis IIS di tingkat server atau situs web:
- Navigasi ke fitur Modul .
- Pilih StaticFileModule dalam daftar.
- Klik Hapus di bilah samping Tindakan .
Peringatan
Jika handler file statis IIS diaktifkan dan ASP.NET Core Module dikonfigurasi dengan salah, file statis dilayani. Ini terjadi, misalnya, jika file web.config tidak disebarkan.
- Tempatkan file kode, termasuk
.cs
dan.cshtml
, di luar akar web proyek aplikasi. Oleh karena itu, pemisahan logis dibuat antara konten sisi klien aplikasi dan kode berbasis server. Ini mencegah kode sisi server bocor.
Melayani file di luar wwwroot dengan memperbarui IWebHostEnvironment.WebRootPath
Kapan IWebHostEnvironment.WebRootPath diatur ke folder selain wwwroot
:
- Di lingkungan pengembangan, aset statis yang ditemukan di keduanya
wwwroot
dan yang diperbaruiIWebHostEnvironment.WebRootPath
disajikan dariwwwroot
. - Di lingkungan apa pun selain pengembangan, aset statis duplikat disajikan dari folder yang diperbarui
IWebHostEnvironment.WebRootPath
.
Pertimbangkan aplikasi web yang dibuat dengan templat web kosong:
Berisi
Index.html
file diwwwroot
danwwwroot-custom
.Dengan file yang diperbarui
Program.cs
berikut yang menetapkanWebRootPath = "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();
Dalam kode sebelumnya, permintaan ke /
:
- Dalam pengembalian lingkungan pengembangan
wwwroot/Index.html
- Di lingkungan apa pun selain pengembalian pengembangan
wwwroot-custom/Index.html
Untuk memastikan aset dari wwwroot-custom
dikembalikan, gunakan salah satu pendekatan berikut:
Hapus aset bernama duplikat di
wwwroot
.Atur
"ASPNETCORE_ENVIRONMENT"
ke nilai apa pun selain"Development"
.Properties/launchSettings.json
Nonaktifkan aset web statis sepenuhnya dengan mengatur
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
dalam file proyek. PERINGATAN, menonaktifkan aset web statis menonaktifkan Razor Pustaka Kelas.Tambahkan JSON berikut ke file proyek:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
Kode berikut diperbarui IWebHostEnvironment.WebRootPath
ke nilai non pengembangan, menjamin konten duplikat dikembalikan dari wwwroot-custom
bukan 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();
Sumber Daya Tambahan:
Oleh Rick Anderson dan Kirk Larkin
File statis, seperti HTML, CSS, gambar, dan JavaScript, adalah aset aplikasi ASP.NET Core berfungsi langsung ke klien secara default.
Melihat atau mengunduh kode sampel (cara mengunduh)
Sajikan file statis
File statis disimpan dalam direktori akar web proyek. Direktori default adalah {content root}/wwwroot
, tetapi dapat diubah dengan UseWebRoot metode . Untuk informasi selengkapnya, lihat Akar konten dan akar Web.
Metode CreateDefaultBuilder ini mengatur akar konten ke direktori saat ini:
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>();
});
}
Kode sebelumnya dibuat dengan templat aplikasi web.
File statis dapat diakses melalui jalur yang relatif terhadap akar web. Misalnya, templat proyek Aplikasi Web berisi beberapa folder dalam wwwroot
folder:
wwwroot
css
js
lib
Pertimbangkan untuk membuat folder wwwroot/images dan menambahkan wwwroot/images/MyImage.jpg
file. Format URI untuk mengakses file di images
folder adalah https://<hostname>/images/<image_file_name>
. Misalnya: https://localhost:5001/images/MyImage.jpg
Menyajikan file di akar web
Templat aplikasi web default memanggil UseStaticFiles metode di Startup.Configure
, yang memungkinkan file statis dilayani:
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();
});
}
Overload metode tanpa UseStaticFiles
parameter menandai file di akar web sebagai servable. Referensi wwwroot/images/MyImage.jpg
markup berikut :
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Dalam kode sebelumnya, karakter ~/
tilde menunjuk ke akar web.
Menyajikan file di luar akar web
Pertimbangkan hierarki direktori tempat file statis untuk dilayani berada di luar akar web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Permintaan dapat mengakses red-rose.jpg
file dengan mengonfigurasi Middleware File Statis sebagai berikut:
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();
});
}
Dalam kode sebelumnya, hierarki direktori MyStaticFiles diekspos secara publik melalui segmen URI StaticFiles . Permintaan untuk https://<hostname>/StaticFiles/images/red-rose.jpg
melayani red-rose.jpg
file.
Referensi MyStaticFiles/images/red-rose.jpg
markup berikut :
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Mengatur header respons HTTP
Objek StaticFileOptions dapat digunakan untuk mengatur header respons HTTP. Selain mengonfigurasi penyajian file statis dari akar web, kode berikut mengatur Cache-Control
header:
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();
});
}
Kode sebelumnya menetapkan usia maksimal hingga 604800 detik (7 hari).
Otorisasi file statis
Templat ASP.NET Core memanggil UseStaticFiles sebelum memanggil UseAuthorization. Sebagian besar aplikasi mengikuti pola ini. Ketika Middleware File Statis dipanggil sebelum middleware otorisasi:
- Tidak ada pemeriksaan otorisasi yang dilakukan pada file statis.
- File statis yang dilayani oleh Middleware File Statis, seperti file di bawah
wwwroot
, dapat diakses secara publik.
Untuk menyajikan file statis berdasarkan otorisasi:
- Simpan di luar
wwwroot
. - Panggil
UseStaticFiles
, menentukan jalur, setelah memanggilUseAuthorization
. - Atur kebijakan otorisasi fallback.
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.
Dalam kode sebelumnya, kebijakan otorisasi fallback mengharuskan semua pengguna diautentikasi. Titik akhir seperti pengontrol, Razor Halaman, dll yang menentukan persyaratan otorisasi mereka sendiri tidak menggunakan kebijakan otorisasi fallback. Misalnya, Razor Halaman, pengontrol, atau metode tindakan dengan [AllowAnonymous]
atau [Authorize(PolicyName="MyPolicy")]
menggunakan atribut otorisasi yang diterapkan daripada kebijakan otorisasi fallback.
RequireAuthenticatedUser menambahkan ke instans DenyAnonymousAuthorizationRequirement saat ini, yang memberlakukan bahwa pengguna saat ini diautentikasi.
Aset statis di bawah wwwroot
dapat diakses secara publik karena Middleware File Statis default (app.UseStaticFiles();
) dipanggil sebelum UseAuthentication
. Aset statis di folder MyStaticFiles memerlukan autentikasi. Kode sampel menunjukkan ini.
Pendekatan alternatif untuk melayani file berdasarkan otorisasi adalah dengan:
- Simpan di luar
wwwroot
dan direktori apa pun yang dapat diakses oleh Middleware File Statis. - Sajikan melalui metode tindakan tempat otorisasi diterapkan dan mengembalikan FileResult objek:
[Authorize]
public IActionResult BannerImage()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
Penjelajahan direktori
Penjelajahan direktori memungkinkan daftar direktori dalam direktori tertentu.
Penjelajahan direktori dinonaktifkan secara default karena alasan keamanan. Untuk informasi selengkapnya, lihat Pertimbangan keamanan untuk file statis.
Aktifkan penjelajahan direktori dengan:
- AddDirectoryBrowser di
Startup.ConfigureServices
. - UseDirectoryBrowser di
Startup.Configure
.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDirectoryBrowser();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// using Microsoft.Extensions.FileProviders;
// using System.IO;
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Kode sebelumnya memungkinkan penjelajahan direktori folder wwwroot/images menggunakan URL https://<hostname>/MyImages
, dengan tautan ke setiap file dan folder:
Melayani dokumen default
Mengatur halaman default memberi pengunjung titik awal di situs. Untuk melayani file default dari wwwroot
tanpa memerlukan URL permintaan untuk menyertakan nama file, panggil UseDefaultFiles metode :
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
harus dipanggil sebelumnya UseStaticFiles
untuk melayani file default. UseDefaultFiles
adalah penulis ulang URL yang tidak melayani file.
Dengan UseDefaultFiles
, permintaan ke folder untuk wwwroot
mencari:
default.htm
default.html
index.htm
index.html
File pertama yang ditemukan dari daftar dilayani seolah-olah permintaan menyertakan nama file. URL browser terus mencerminkan URI yang diminta.
Kode berikut mengubah nama file default menjadi mydefault.html
:
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
Kode berikut menunjukkan Startup.Configure
dengan kode sebelumnya:
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 untuk dokumen default
UseFileServer menggabungkan fungsionalitas UseStaticFiles
, UseDefaultFiles
, dan secara UseDirectoryBrowser
opsional .
Panggil app.UseFileServer
untuk mengaktifkan penyajian file statis dan file default. Penjelajahan direktori tidak diaktifkan. Kode berikut menunjukkan Startup.Configure
dengan 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();
});
}
Kode berikut memungkinkan penyajian file statis, file default, dan penjelajahan direktori:
app.UseFileServer(enableDirectoryBrowsing: true);
Kode berikut menunjukkan Startup.Configure
dengan kode sebelumnya:
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();
});
}
Pertimbangkan hierarki direktori berikut:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
Kode berikut memungkinkan penyajian file statis, file default, dan penjelajahan direktori dari MyStaticFiles
:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDirectoryBrowser();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(); // For the wwwroot folder.
// using Microsoft.Extensions.FileProviders;
// using System.IO;
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
AddDirectoryBrowser harus dipanggil ketika EnableDirectoryBrowsing
nilai properti adalah true
.
Menggunakan hierarki file dan kode sebelumnya, URL diselesaikan sebagai berikut:
URI | Respons |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Jika tidak ada file bernama default di direktori MyStaticFiles, https://<hostname>/StaticFiles
mengembalikan daftar direktori dengan tautan yang dapat diklik:
UseDefaultFiles dan UseDirectoryBrowser lakukan pengalihan sisi klien dari URI target tanpa mengikuti /
URI target dengan trailing /
. Misalnya, dari https://<hostname>/StaticFiles
ke https://<hostname>/StaticFiles/
. URL relatif dalam direktori StaticFiles tidak valid tanpa garis miring berikutnya (/
).
FileExtensionContentTypeProvider
Kelas FileExtensionContentTypeProvider berisi Mappings
properti yang berfungsi sebagai pemetaan ekstensi file ke jenis konten MIME. Dalam sampel berikut, beberapa ekstensi file dipetakan ke jenis MIME yang diketahui. Ekstensi .rtf diganti, dan .mp4 dihapus:
// 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"
});
Kode berikut menunjukkan Startup.Configure
dengan kode sebelumnya:
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();
});
}
Lihat Jenis konten MIME.
Jenis konten non-standar
Middleware File Statis memahami hampir 400 jenis konten file yang diketahui. Jika pengguna meminta file dengan jenis file yang tidak diketahui, Middleware File Statis meneruskan permintaan ke middleware berikutnya dalam alur. Jika tidak ada middleware yang menangani permintaan, respons 404 Tidak Ditemukan dikembalikan. Jika penjelajahan direktori diaktifkan, tautan ke file ditampilkan dalam daftar direktori.
Kode berikut memungkinkan penyajian jenis yang tidak diketahui dan merender file yang tidak diketahui sebagai gambar:
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
Kode berikut menunjukkan Startup.Configure
dengan kode sebelumnya:
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();
});
}
Dengan kode sebelumnya, permintaan untuk file dengan jenis konten yang tidak diketahui dikembalikan sebagai gambar.
Peringatan
Mengaktifkan ServeUnknownFileTypes adalah risiko keamanan. Ini dinonaktifkan secara default, dan penggunaannya tidak disarankan. FileExtensionContentTypeProvider menyediakan alternatif yang lebih aman untuk melayani file dengan ekstensi non-standar.
Menyajikan file dari beberapa lokasi
UseStaticFiles
dan UseFileServer
default ke penyedia file yang menunjuk ke wwwroot
. Instans tambahan dan UseStaticFiles
UseFileServer
dapat disediakan dengan penyedia file lain untuk melayani file dari lokasi lain. Untuk informasi lebih lanjut, lihat masalah GitHub ini.
Pertimbangan keamanan untuk file statis
Peringatan
UseDirectoryBrowser
dan UseStaticFiles
dapat membocorkan rahasia. Menonaktifkan penjelajahan direktori dalam produksi sangat disarankan. Tinjau direktori mana yang diaktifkan dengan hati-hati melalui UseStaticFiles
atau UseDirectoryBrowser
. Seluruh direktori dan sub-direktorinya dapat diakses secara publik. Simpan file yang cocok untuk dilayani ke publik di direktori khusus, seperti <content_root>/wwwroot
. Pisahkan file-file ini dari tampilan MVC, Razor Halaman, file konfigurasi, dll.
URL untuk konten yang diekspos dengan
UseDirectoryBrowser
danUseStaticFiles
tunduk pada sensitivitas kasus dan pembatasan karakter dari sistem file yang mendasar. Misalnya, Windows tidak peka huruf besar/kecil, tetapi macOS dan Linux tidak.ASP.NET aplikasi Core yang dihosting di IIS menggunakan Modul Inti ASP.NET untuk meneruskan semua permintaan ke aplikasi, termasuk permintaan file statis. Handler file statis IIS tidak digunakan dan tidak memiliki kesempatan untuk menangani permintaan.
Selesaikan langkah-langkah berikut di Manajer IIS untuk menghapus handler file statis IIS di tingkat server atau situs web:
- Navigasi ke fitur Modul .
- Pilih StaticFileModule dalam daftar.
- Klik Hapus di bilah samping Tindakan .
Peringatan
Jika handler file statis IIS diaktifkan dan ASP.NET Core Module dikonfigurasi dengan salah, file statis dilayani. Ini terjadi, misalnya, jika file web.config tidak disebarkan.
- Tempatkan file kode, termasuk
.cs
dan.cshtml
, di luar akar web proyek aplikasi. Oleh karena itu, pemisahan logis dibuat antara konten sisi klien aplikasi dan kode berbasis server. Ini mencegah kode sisi server bocor.
Sumber Daya Tambahan:
ASP.NET Core