【问题标题】:Can an Owin Middleware return a response earlier than the Invoke method returns?Owin 中间件能否在 Invoke 方法返回之前返回响应?
【发布时间】:2016-04-27 08:26:12
【问题描述】:

我有以下中间件代码:

public class UoWMiddleware : OwinMiddleware
{
    readonly IUoW uow;
    public UoWMiddleware(OwinMiddleware next, IUoW uow) : base(next)
    {
        this.uow = uow;
    }

    public override async Task Invoke(IOwinContext context)
    {
        try
        {
            await Next.Invoke(context);
        }
        catch
        {
            uow.RollBack();
            throw;
        }
        finally
        {
            if (uow.Status == Base.SharedDomain.UoWStatus.Running)
            {
                var response = context.Response;
                if (response.StatusCode < 400)
                {
                    Thread.Sleep(1000);
                    uow.Commit();
                }
                else
                    uow.RollBack();
            }
        }
    }
}

有时我们会观察到响应在通过 fiddler 调用 uow.Commit() 之前返回给客户端。例如,我们在 uow.Commit 中设置了一个断点,我们看到响应返回给客户端,尽管我们正在等待断点。这有些出乎意料。我认为响应将在 Invoke 方法结束后严格返回。我错过了什么吗?

【问题讨论】:

    标签: asp.net-web-api owin middleware


    【解决方案1】:

    在 Owin/Katana 中,响应正文(当然还有标头)在中间件在 IOwinContextResponse 对象上调用 Write 的精确时刻发送到客户端。

    这意味着如果您的 next 中间件正在编写响应正文,您的客户端将在您的服务器端代码从对 await Next.Invoke() 的调用返回之前收到它。

    这就是 Owin 的设计方式,取决于响应流在单个请求/响应生命周期中可能只写入一次这一事实。

    查看您的代码,我看不出这种行为有任何重大问题,因为您只是在将响应写入流后读取响应标头,因此不会更改它。

    相反,如果您需要更改下一个中间件写入的响应,或者您严格需要在在服务器端执行进一步的逻辑之后写入响应,那么您唯一的选择就是缓冲将响应主体放入内存流中,然后在您准备好时将其复制到真正的响应流 (as per this answer) 中。

    我已经在不同的用例(但共享相同的概念)中成功测试了这种方法,您可能会发现查看此答案:https://stackoverflow.com/a/36755639/3670737

    参考:
    Changing the response object from OWIN Middleware

    【讨论】:

    • 让我澄清一下。在我的 owin 方法返回之前,我正在观察响应已“完成”。所以你说这是设计使然吗?
    • 是的,响应是在中间件调用 Write 的同时发送的,我认为这发生在您的 next 中间件中(例如 Web API) .这就是为什么您在方法返回之前在 fiddler 中看到 HTTP 响应的原因。
    • 是的,显然你是对的。就我而言,我只是想抓住发送响应的那一刻。所以 OnSendingHeaders 回调是我想要的。您的帖子将我引向正确的方向。
    猜你喜欢
    • 2019-08-30
    • 2013-06-03
    • 2016-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-21
    • 1970-01-01
    相关资源
    最近更新 更多