为何ASP.NET Core Web API需加空app.Run()?已有带参Run仍需吗?
带参
app.Run()加了之后,为啥还要调用空的app.Run()才能启动Web API? 你搞混了ASP.NET Core里两个同名但功能完全不同的Run()方法:
app.Run(RequestDelegate):这是给请求管道添加终端中间件的方法,作用是定义管道的最后执行逻辑,不会再调用后续中间件,但它只管配置管道,不会启动服务监听请求。app.Run():这才是启动Web主机、开始监听HTTP请求的方法,调用后程序会阻塞当前线程,持续等待请求直到应用停止。
你的代码里只添加了终端中间件(带参的app.Run(...)),但没调用启动服务的无参app.Run(),所以程序在配置完管道后就直接执行完毕退出了,自然不会启动浏览器或监听端口。
另外你的代码还有个关键问题:中间件注册顺序错误。你把自定义的app.Use()和app.Run()放在了MapControllers()之后,这会导致这些自定义逻辑永远不会被执行——因为MapControllers()匹配到控制器路由后,会直接短路后续的管道流程,不会再往后执行其他中间件。正确的顺序是把自定义中间件放在MapControllers()之前。
修正后的代码参考:
var builder = WebApplication.CreateBuilder(args); // 注册服务 builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // 配置请求管道 if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); // 自定义中间件放在MapControllers()之前,才能被执行 app.Use(async (context, next) => { await context.Response.WriteAsync("Before Invoke from 1st app.Use()\n"); await next(); await context.Response.WriteAsync("After Invoke from 1st app.Use()\n"); }); app.Use(async (context, next) => { await context.Response.WriteAsync("Before Invoke from 2nd app.Use()\n"); await next(); await context.Response.WriteAsync("After Invoke from 2nd app.Use()\n"); }); app.Run(async (context) => { await context.Response.WriteAsync("Hello from 1st app.Run()\n"); }); // 必须调用这个启动服务监听 app.Run();
总结:
- 带参
app.Run(...)仅负责添加终端中间件,必须调用无参app.Run()(或异步的app.RunAsync())才能启动应用的请求监听服务。 - 中间件注册顺序至关重要,自定义逻辑需放在路由匹配类中间件(如
MapControllers())之前,否则无法被执行。
内容的提问来源于stack exchange,提问作者Hax
相关产品推荐
相关产品推荐

