Blazor项目本地调试正常,发布后因防伪造中间件配置问题无法加载页面
我太懂这种本地跑顺风顺水,一发布就掉坑里的烦躁了!折腾好几个小时肯定头大,咱们先看你遇到的错误提示:
InvalidOperationException: Endpoint / (/) contains anti-forgery metadata, but a middleware was not found that supports anti-forgery. Configure your application startup by adding app.UseAntiforgery() in the application startup code. If there are calls to app.UseRouting() and app.UseEndpoints(...), the call to app.UseAntiforgery() must go between them. Calls to app.UseAntiforgery() must be placed after calls to app.UseAuthentication() and app.UseAuthorization().
你本地调试正常但发布后报错的核心原因是:开发环境下的UseWebAssemblyDebugging中间件帮你自动兼容了部分防伪造逻辑,掩盖了中间件顺序错误的问题;但生产环境(发布后)没有这个调试中间件,错误就直接暴露出来了。
看你的program.cs,中间件顺序存在几个关键问题,这就是罪魁祸首:
UseHttpsRedirection、UseStaticFiles这类基础中间件被放在了路由相关中间件之后,完全不符合ASP.NET Core的中间件执行顺序规范UsePathBase被放在了组件映射之后,导致路径基配置没有生效在路由匹配上- 虽然
UseAntiforgery在UseRouting和UseEndpoints之间,但前面的顺序错误导致它无法正确关联到Blazor组件的防伪造元数据
下面是修正后的program.cs代码,我标注了关键修改点:
using Microsoft.ApplicationInsights; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Mvc; using MudBlazor.Services; using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; var builder = WebApplication.CreateBuilder(args); // Add MudBlazor services builder.Services.AddMudServices(); // Add services to the container. builder.Services .AddRazorComponents() .AddInteractiveWebAssemblyComponents(); builder.Services .AddControllers() .AddJsonOptions(opts => { opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); opts.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; }); var app = builder.Build(); if (builder.Environment.IsDevelopment()) { app.UseWebAssemblyDebugging(); app.UseDeveloperExceptionPage(); } else { // 生产环境补充全局异常处理和HSTS app.UseExceptionHandler("/Error"); app.UseHsts(); } // 1. 先配置路径基,必须在所有路由相关操作之前 app.UsePathBase("/foo/bar"); // 2. 基础中间件放在路由处理之前 app.UseHttpsRedirection(); app.UseStaticFiles(); // 3. 路由相关中间件严格按顺序执行 app.UseRouting(); // 后续如果添加身份验证/授权,要放在UseAntiforgery之前 // app.UseAuthentication(); // app.UseAuthorization(); app.UseAntiforgery(); app.UseEndpoints(e => e.MapControllers()); app.MapRazorComponents<App>() .AddInteractiveWebAssemblyRenderMode() .AddAdditionalAssemblies(typeof(Foo.Bar.WebClient._Imports).Assembly); await app.RunAsync();
关键修改说明:
- 把
UsePathBase移到最靠前的位置:路径基配置必须在所有路由、组件映射前执行,这样后续所有请求都会基于这个路径处理 - 调整
UseHttpsRedirection、UseStaticFiles到UseRouting之前:这类中间件不需要路由信息,应该在路由匹配前完成处理 - 为生产环境补充了异常处理页和HSTS配置,提升生产环境的稳定性
- 预留了身份验证/授权的位置(如果后续需要添加),完全符合错误提示里的要求
修改完成后,重新执行dotnet publish,再启动程序应该就能正常加载页面了!
备注:内容来源于stack exchange,提问作者Dr Schizo

