Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Catatan
Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 9 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 9 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 9 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.
Menyajikan 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 direktori 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();
Metode overload tanpa parameter UseStaticFiles
menandai file di root web sebagai dapat disajikan. Markup berikut merujuk ke wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Dalam markup sebelumnya, karakter tilde ~
mengarah ke root 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 berkas red-rose.jpg
dengan mengonfigurasi Static File Middleware 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
menyajikan berkas red-rose.jpg
.
Referensi markup berikut ini MyStaticFiles/images/red-rose.jpg
:
<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 root 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 mereka 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 DenyAnonymousAuthorizationRequirement ke instans saat ini, yang memastikan bahwa pengguna saat ini telah 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 elemen-elemen tersebut 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 untuk setiap 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.
Menyediakan 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 di 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();
Menggunakan UseFileServer untuk dokumen bawaan
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 | Tanggapan |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Jika tidak ada file dengan nama 'default' yang ada di direktori MyStaticFiles, https://<hostname>/StaticFiles
akan mengembalikan daftar direktori dengan tautan yang dapat diklik.
Daftar file statis
UseDefaultFiles dan UseDirectoryBrowser melakukan pengalihan sisi klien dari URI target tanpa diakhiri /
ke URI target yang diakhiri /
. Misalnya, dari https://<hostname>/StaticFiles
ke https://<hostname>/StaticFiles/
. URL relatif dalam direktori StaticFiles tidak valid tanpa garis miring penutup (/
) kecuali opsi DefaultFilesOptionsRedirectToAppendTrailingSlash 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
secara default ke penyedia file yang mengarah ke wwwroot
. Instans tambahan dari UseStaticFiles
dan UseFileServer
dapat disediakan dengan penyedia file lain untuk menyajikan file dari lokasi lain. Contoh berikut memanggil UseStaticFiles
dua kali untuk menyajikan file dari wwwroot
dan 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 Tag ImageAppendVersion 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 ASP.NET Core Blazor static files.
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.Aplikasi ASP.NET Core yang dihosting di IIS menggunakan Modul ASP.NET Core untuk meneruskan semua permintaan ke aplikasi, termasuk permintaan untuk 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 akan disajikan. 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
wwwroot
dan diIWebHostEnvironment.WebRootPath
yang telah diperbarui diproses 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 /
:
- Pada lingkungan pengembangan, kembalikan
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 yang bernama sama di
wwwroot
.Atur
"ASPNETCORE_ENVIRONMENT"
ke nilai apa pun selainProperties/launchSettings.json
."Development"
Nonaktifkan aset web statis sepenuhnya dengan mengatur
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
dalam file proyek. PERINGATAN, menonaktifkan aset web statis akan 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.
Layani 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
Melayani file di direktori root 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();
Metode overload tanpa parameter UseStaticFiles
menandai file di root web sebagai dapat dihidangkan. Markup berikut mengacu pada wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Dalam markup sebelumnya, karakter ~
tilde menunjuk ke direktori root 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 berkas red-rose.jpg
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 ke https://<hostname>/StaticFiles/images/red-rose.jpg
menyediakan file red-rose.jpg
.
Berikut referensi penandaan MyStaticFiles/images/red-rose.jpg
:
<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 root web, kode berikut mengatur tajuk 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 DenyAnonymousAuthorizationRequirement ke instans saat ini, yang memastikan bahwa pengguna saat ini telah 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. - Lakukan penyajian melalui metode aksi yang menerapkan otorisasi dan mengembalikan objek FileResult.
[Authorize]
public class BannerImageModel : PageModel
{
private readonly IWebHostEnvironment _env;
public BannerImageModel(IWebHostEnvironment env) =>
_env = env;
public PhysicalFileResult OnGet()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
}
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.
Menyediakan dokumen standar
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 di 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 | Tanggapan |
---|---|
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
akan menampilkan daftar direktori dengan tautan yang dapat diklik.
UseDefaultFiles dan UseDirectoryBrowser melakukan pengalihan sisi klien dari URI target tanpa trailing /
ke URI target dengan trailing /
. Misalnya, dari https://<hostname>/StaticFiles
ke https://<hostname>/StaticFiles/
. URL relatif dalam direktori StaticFiles tidak valid tanpa garis miring di akhir (/
) kecuali opsi DefaultFilesOptions dari RedirectToAppendTrailingSlash 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 mengarah ke wwwroot
. Instans tambahan dari UseStaticFiles
dan UseFileServer
dapat disediakan dengan penyedia file lain untuk menyediakan file dari lokasi lain. Contoh berikut memanggil UseStaticFiles
dua kali untuk melayani file dari kedua wwwroot
dan 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 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.Aplikasi ASP.NET Core yang di-hosting di IIS menggunakan Modul ASP.NET Core untuk meneruskan semua permintaan ke aplikasi, termasuk permintaan untuk 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:
- Arahkan ke fitur Modul.
- Pilih StaticFileModule dalam daftar.
- Klik Hapus di bilah tindakan di samping.
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 terdapat pada
wwwroot
danIWebHostEnvironment.WebRootPath
yang telah diperbarui 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:
Mengandung sebuah
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 /
:
- Kembali ke 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 dengan nama duplikat di
wwwroot
.Atur
"ASPNETCORE_ENVIRONMENT"
ke nilai apa pun selainProperties/launchSettings.json
."Development"
Nonaktifkan aset web statis sepenuhnya dengan mengatur
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
dalam file proyek. .PERINGATAN, menonaktifkan aset web statis akan menyebabkan Pustaka Kelas dinonaktifkan 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)
Menyajikan berkas 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
Menyimpan file di direktori root 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 parameter UseStaticFiles
menandai file di akar web sebagai dapat disajikan. Referensi wwwroot/images/MyImage.jpg
markup berikut :
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Dalam kode sebelumnya, karakter ~/
tilde mengacu ke root 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
Sebuah permintaan dapat mengakses file red-rose.jpg
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 ke https://<hostname>/StaticFiles/images/red-rose.jpg
menyajikan berkas red-rose.jpg
.
Referensi markup berikut ini:
<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 pengganti.
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 aksi yang menggunakan [AllowAnonymous]
atau [Authorize(PolicyName="MyPolicy")]
lebih memilih atribut otorisasi yang diterapkan daripada kebijakan otorisasi fallback.
RequireAuthenticatedUser menambahkan DenyAnonymousAuthorizationRequirement ke instans saat ini, yang memastikan bahwa pengguna saat ini sudah 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
Penelusuran direktori memungkinkan penampilan 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:
Menyediakan 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 dalam 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();
});
}
Gunakan UseFileServer untuk dokumen bawaan
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 | Tanggapan |
---|---|
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
akan menampilkan daftar isi direktori dengan tautan yang dapat diklik.
UseDefaultFiles dan UseDirectoryBrowser melakukan pengalihan sisi klien dari URI target tanpa trailing /
ke URI target dengan trailing /
. Misalnya, dari https://<hostname>/StaticFiles
ke https://<hostname>/StaticFiles/
. URL relatif dalam direktori StaticFiles tidak valid tanpa garis miring di akhir (/
).
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 UseStaticFiles
dan UseFileServer
dapat disediakan dengan penyedia file lain untuk menyediakan 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.Aplikasi ASP.NET Core yang dihosting di IIS menggunakan ASP.NET Core Module untuk meneruskan semua permintaan ke app, termasuk permintaan berkas 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:
- Navigasikan 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