You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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();

总结:

  1. 带参app.Run(...)仅负责添加终端中间件,必须调用无参app.Run()(或异步的app.RunAsync())才能启动应用的请求监听服务。
  2. 中间件注册顺序至关重要,自定义逻辑需放在路由匹配类中间件(如MapControllers())之前,否则无法被执行。

内容的提问来源于stack exchange,提问作者Hax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 03:01:22