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

CLI运行ASP.NET Core项目报错,Visual Studio运行正常求原因

问题:ASP.NET Core项目在CLI与Visual Studio运行时的异常差异分析

项目代码

Program.cs

using Platform;

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.Use(async (context, next) =>
{
    try
    {
        await next();
    }
    catch (Exception e)
    {
        await context.Response.WriteAsync(e.ToString());
        await context.Response.WriteAsync($"\n{e.TargetSite}");
    }
});

app.Map("/branch", branchBuilder =>
{
    branchBuilder.UseMiddleware<QueryStringMiddleware>();
    branchBuilder.Use(async (context, next) =>
    {
        await context.Response.WriteAsync("branch");
        await next(context);
    });
});
app.MapGet("/", () => "Hello World!");

app.Run();

QueryStringMiddleware.cs

namespace Platform
{
    public class QueryStringMiddleware
    {
        private RequestDelegate next;

        public QueryStringMiddleware(RequestDelegate next)
        {
            this.next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            if (context.Request.Method == HttpMethods.Get &&
                context.Request.Query["custom"] == "true")
            {
                if (!context.Response.HasStarted)
                {
                    context.Response.ContentType= "text/plain";
                }

                await context.Response.WriteAsync("class middleware\n");
            }
            await next(context);
        }

        public static async Task Jip(HttpContext context)
        {
            await context.Response.WriteAsync("jipjip\n");
        }
    }
}

问题现象

  • 通过CLI运行项目,发起/branch?custom=true请求时抛出异常,异常信息如下:
class middleware
branchSystem.InvalidOperationException: StatusCode cannot be set because the response has already started.

at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ThrowResponseAlreadyStartedException(String value)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.set_StatusCode(Int32 value)
at Microsoft.AspNetCore.Builder.ApplicationBuilder.<>c.b__18_0(HttpContext context)
at Program.<>c.<<$>b__0_3>d.MoveNext() in D:\develop\Platform\Program.cs:line 28
--- End of stack trace from previous location ---
at Platform.QueryStringMiddleware.Invoke(HttpContext context) in D:\develop\Platform\Middleware.cs:line 23
at Microsoft.AspNetCore.Builder.Extensions.MapMiddleware.InvokeCore(HttpContext context, PathString matchedPath, PathString remainingPath)
at Program.<>c.<<$>b__0_0>d.MoveNext() in D:\develop\Platform\Program.cs:line 13
Void ThrowResponseAlreadyStartedException(System.String)
  • 在Visual Studio中运行相同项目并发起该请求,无异常,响应正常。

差异原因分析

核心差异源于两种运行环境的响应状态码处理逻辑不同:

  1. 请求进入/branch分支的中间件链后,QueryStringMiddleware和后续的匿名中间件已经向响应流写入了内容,此时Response.HasStarted标记为true。
  2. 分支内未配置任何终结点(如MapGet),ASP.NET Core框架会尝试返回404状态码以表示请求路径未匹配到处理逻辑。
  3. CLI启动时默认使用Kestrel服务器,Kestrel遵循严格的HTTP规范:当响应流已启动(即已向客户端发送数据),不允许再修改状态码,因此直接抛出StatusCode cannot be set because the response has already started异常。
  4. Visual Studio默认使用IIS Express运行,IIS Express的响应处理逻辑为了开发便利放宽了限制,允许在响应已启动的情况下设置状态码(或忽略该错误继续完成响应),因此不会触发异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 05:20:22