【问题标题】:ASP.NET Web API HttpContext Response is sent back before IOwinContext ResponseASP.NET Web API HttpContext 响应在 IOwinContext 响应之前发回
【发布时间】:2017-06-16 15:31:51
【问题描述】:

我们在 IIS 中托管的 ASP.NET Web API 2 项目中使用 Owin 中间件。

我目前遇到了一个奇怪的现象,即 IOwinContext.Response.Body 没有被写入,实际上,即使我在唤醒 Next.Invoke() 后在中间件中设置了断点,它也会被命中,即使我还没有继续,响应已经发送回服务器。

当我查看 IOwinContext 上的响应正文时,它是空的。但是,我可以从 HttpContext.Response.Filter 获得响应。当我使用 HttpContext 并达到断点时,在我继续之前不会发回响应。下面是我们的 Startup.cs 类中使用的当前配置方法。

public async void Configuration(IAppBuilder app)
{
    try
    {
        // Global Config
        var config = GlobalConfiguration.Configuration;

        // configure dependency injection
        UnityConfig.RegisterComponents();

        // configure log for net
        log4net.Config.XmlConfigurator.Configure();

        // turn around all requests right here
        app.Use(async (context, next) =>
        {
            if (context.Request.Path.ToString() == "/")
            {
                string text = "UP";
                context.Response.StatusCode = 200;
                context.Response.ReasonPhrase = text;
                await context.Response.WriteAsync(text);
                return;
            }

            await next.Invoke();
        });

        // Handle exceptions in the OWIN layer here
        app.UseUncaughtExceptionHandler();

        // add cors headers
        app.Use(async (context, next) => { });

        // some UI stuff
        app.Use(async (context, next) => { });

        // Log Request Metrics
        app.UseLogRequestMetrics();

        // Evaluate Partner Key
        app.MapWhen(context => Regex.IsMatch(context.Request.Uri.PathAndQuery.ToLower(), @"/api"), newApp =>
        {
#if !DEBUG
            newApp.Use<Middleware1>();
#endif
            newApp.Use<Middleware2>();

            newApp.Use<Middleware3>(); // On the response path back, the IOwinResponse body is already empty
        });

        WebApiConfig.Register(config);

        app.UseWebApi(config); // It seems like I'm losing the response in here, but I don't really know

        config.EnsureInitialized();

        // Configure object mapping
        AutoMapperConfig.Configure();
    }
    catch (Exception ex)
    {
        await LogForNetErrorLogger.LogError(ex);
    }
}

我很确定我的中间件搞砸了,但是在等待 Next.Invoke() 之后,响应在返回到我的第一个中间件 (Middleware3) 之前已经消失了

任何见解或发人深省的想法将不胜感激。另外,如果这些信息还不够,请告诉我。

【问题讨论】:

    标签: c# asp.net iis asp.net-web-api2 owin-middleware


    【解决方案1】:

    所以,正如我在上面的帖子中一样,我认为问题在于 HttpResponse 在 IOwinResponse 之前被发回。事实证明,我完全忽略了映射部分:

    app.MapWhen(context => Regex.IsMatch(context.Request.Uri.PathAndQuery.ToLower(), @"/api"), newApp =>
    {
    #if !DEBUG
        newApp.Use<Middleware1>();
    #endif
        newApp.Use<Middleware2>();
    
        newApp.Use<Middleware3>();
    });
    

    当您使用app.Map() 时,它会分支中间件。因此,如果路径匹配“/api”,它将分支。但是,它仍在使用app.UseWebApi() 组件,这就是为什么我有两个不同的响应以及为什么我期望的响应没有写入Middleware3 组件的IOwinContext。 我通过删除 app.MapWhen() 方法来修复它,将其更改为:

    app.MapWhen(context => Regex.IsMatch(context.Request.Uri.PathAndQuery.ToLower(), @"/site"), newApp =>
    {
    #if !DEBUG
        newApp.Use<Middleware1>();
    #endif
        newApp.Use<Middleware2>();
    
        newApp.Use<Middleware3>(); // On the response path back, the IOwinResponse body is already empty
    });
    

    到这里:

    #if !DEBUG
    newApp.Use<Middleware1>();
    #endif
    newApp.Use<Middleware2>();
    
    newApp.Use<Middleware3>();
    

    并将这段代码放在中间件组件Middleware1Middleware2Middleware3的开头:

    public override async Task Invoke(IOwinContext context)
    {
        if (!context.Request.Path.ToString().StartsWith("/api/"))
        {
            await Next.Invoke(context);
    
            return;
        }
    
        // stuff I want to run if the above doesn't match
        await Next.Invoke(context);
    
        ...
    }
    

    好吧,至少修复很简单,即使我花了三周时间才找到它。如果你想了解 IAppBuilder.MapWhen 扩展方法,这里有一些文档https://msdn.microsoft.com/en-us/library/owin.mapwhenextensions.mapwhen(v=vs.113).aspx

    【讨论】:

      猜你喜欢
      • 2011-09-12
      • 2018-07-09
      • 1970-01-01
      • 2014-07-01
      • 2012-11-29
      • 1970-01-01
      • 2019-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多