如何让自定义中间件捕获Piranha CMS的/uploads请求?
解决Piranha CMS中/uploads路径请求无法被自定义中间件捕获的问题
问题背景
在使用Piranha CMS时,针对/uploads路径下的图片或文件请求无法被自定义中间件捕获。经排查发现,调用UseCms时会自动添加PiranhaStartupFilter,它会在ApplicationBuilder中提前注册UseStaticFiles(),导致静态文件请求直接被返回,无法流向后续自定义中间件。
相关代码如下:
serviceBuilder.Services.AddTransient<IStartupFilter, PiranhaStartupFilter>();
PiranhaStartupFilter的Configure方法:
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next) { return builder => { builder .UseSecurityMiddleware() .UseStaticFiles() .UseMiddleware<RoutingMiddleware>() .UseMiddleware<SitemapMiddleware>(); next(builder); }; }
期望/uploads/foo.jpg这类请求能被以下方式注册的自定义中间件捕获:
app.UsePiranha(options => { options.Builder.CustomImageTools(); });
但目前仅非静态文件及favicon请求能到达该中间件的InvokeAsync方法。
解决方案
方案1:移除默认PiranhaStartupFilter,手动控制中间件顺序
默认的PiranhaStartupFilter会在自定义中间件之前注册UseStaticFiles(),导致静态文件请求提前被处理。我们可以先移除这个过滤器,再手动按正确顺序注册所有中间件:
- 移除默认的
PiranhaStartupFilter
在添加Piranha服务的代码后,执行以下操作:
var piranhaFilter = services.FirstOrDefault(s => s.ServiceType == typeof(IStartupFilter) && s.ImplementationType == typeof(PiranhaStartupFilter)); if (piranhaFilter != null) { services.Remove(piranhaFilter); }
- 手动配置中间件顺序
确保自定义中间件在UseStaticFiles()之前注册:
app.UsePiranha(options => { // 先注册自定义中间件 options.Builder.CustomImageTools(); // 按顺序注册Piranha核心中间件 options.Builder .UseSecurityMiddleware() .UseStaticFiles() .UseMiddleware<RoutingMiddleware>() .UseMiddleware<SitemapMiddleware>(); });
方案2:修改StaticFileOptions,排除/uploads路径
如果不想移除默认的PiranhaStartupFilter,可以通过配置静态文件选项,让默认中间件忽略/uploads路径的请求,使这些请求能流向自定义中间件:
app.UsePiranha(options => { // 先注册自定义中间件 options.Builder.CustomImageTools(); // 替换默认的UseStaticFiles,添加路径过滤 options.Builder.UseStaticFiles(new StaticFileOptions { // 只处理非/uploads开头的请求 Predicate = ctx => !ctx.Request.Path.StartsWithSegments("/uploads") }); // 继续注册其他Piranha中间件 options.Builder .UseSecurityMiddleware() .UseMiddleware<RoutingMiddleware>() .UseMiddleware<SitemapMiddleware>(); });
内容的提问来源于stack exchange,提问作者atoms
相关产品推荐
相关产品推荐

