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目录下的编译时就有的静态文件。
这样就同时解决了开头提出的两个问题。