.NET9新增的MapStaticAssets覆蓋UseStaticFiles配置導致的兩個問題:1.新上傳圖片404;2. 自定義mime .avif輸出標頭錯誤
0. 問題
0.1 問題1,新上傳圖片404打不開
.NET9 WebApp部署到Ubuntu 24.04
網頁看上去訪問都正常,繼續測試,上傳圖片后,發現圖片無法顯示,直接用url訪問404。自己ftp上傳上去的圖片也無法顯示,即使權限加到最高也沒有用。
項目發布時就有的圖片訪問一切正常
0.2 問題2 [ 20250513]新增:自定義mime .avif輸出標頭錯誤
對app.UseStaticFiles();增加自定義mime類型比如.avif后,圖片文件可以下載,但不能直接打開,查看標頭顯示是application/octet-stream,不是預期的image/avif
1. 原因
.NET9 新增了MapStaticAssets,可以對css, js等在編譯時就提供極高的壓縮比,縮小90%左右。大多數情況可以取代UseStaticFiles。
| File | Original | Compressed | % Reduction |
|---|---|---|---|
| bootstrap.min.css | 163 | 17.5 | 89.26% |
| jquery.js | 89.6 | 28 | 68.75% |
| bootstrap.min.js | 78.5 | 20 | 74.52% |
| Total | 331.1 | 65.5 | 80.20% |
但其僅對發布時就有的資源有效。使用中新上傳的文件不起作用,且新上傳的文件url訪問直接404。
由于對wwwroot同時啟用了MapStaticAssets和UseStaticFiles,MapStaticAssets會覆蓋UseStaticFiles的配置,這就導致輸出的標頭不正確。
2. 解決辦法
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
var myprovider = new Microsoft.AspNetCore.StaticFiles.FileExtensionContentTypeProvider();
myprovider.Mappings.Add(".apk", "application/vnd.android.package-archive");
myprovider.Mappings.Add(".ipa", "application/octet-stream.ipa");
myprovider.Mappings.Add(".avif", "image/avif"); //增加.avif mime類型
// 配置靜態文件中間件,解決新上傳圖片404問題
app.UseStaticFiles(new StaticFileOptions
{
//僅對項目根目錄下的upload文件夾生效,其他的由MapStaticAssets搞定,解決自定義mime .avif輸出標頭錯誤
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "upload")),
RequestPath = "/upload",
ContentTypeProvider = myprovider //設置不限制content-type 該設置可以下載所有類型的文件,但是不建議這么設置,因為不安全
});
app.UseRouting();
app.UseAuthorization();
app.MapStaticAssets(); // 使用 MapStaticAssets編譯時優化css,js等資源的尺寸,針對wwwroot文件夾
// Map static assets with a custom path, 第二種避免沖突的解決辦法
//app.MapStaticAssets("wwwroot/custom-assets");
app.MapRazorPages()
.WithStaticAssets();
app.Run();
增加這句:app.UseStaticFiles(); 并設置僅對upload(在項目根目錄,不在wwwroot下)文件夾生效,用于處理上傳的文件,可以自定義mime類型。
而MapStaticAssets處理wwwroot目錄下的編譯時就有的靜態文件。
這樣就同時解決了開頭提出的兩個問題。

浙公網安備 33010602011771號