温馨提示:本文翻译自stackoverflow.com,查看原文请点击:c# - Changing the response object from OWIN Middleware
asp.net-web-api c# owin katana

c# - 从OWIN中间件更改响应对象

发布于 2020-03-29 21:32:40

我的OWIN中间件就是这样。(框架是ASP.NET Web API)。

public class MyMiddleware : OwinMiddleware
{
    public MyMiddleware(OwinMiddleware next) : base(next) { }

    public override async Task Invoke(OwinRequest request, OwinResponse response)
    {
        var header = request.GetHeader("X-Whatever-Header");

        await Next.Invoke(request, response);

        response.SetHeader("X-MyResponse-Header", "Some Value");
        response.StatusCode = 403;

    }
}

问题:

  1. 是从中得出的推荐做法OwinMiddleware吗?我在Katana源代码中看到,一些中间件类是从中派生的,OwinMiddleware而有些则不是。

  2. 我可以看到请求标头。Next.Invoke在我的中间件中设置响应标头或状态代码对返回给客户端的响应没有影响。但是,如果我在Next.Invoke调用之前设置了响应标头或状态,则带有标头和我设置的状态的响应将返回给客户端。设置这些的正确方法是什么?

查看更多

提问者
Badri
被浏览
66
Youssef Moussaoui 2015-06-02 08:47
  1. 是的,建议从OwinMiddleware派生。某些中间件类之所以不能从OwinMiddleware派生,是因为它们是最近才引入的,所以它们尚未切换。或者为避免由于某种原因使程序集依赖于Microsoft.Owin程序集。

  2. 在调用“在下一步上调用”后,在响应上设置内容的可能原因不起作用,因为一旦有人开始写入响应主体流,就会立即发送响应HTTP标头。因此,在中间件组件开始写入响应主体之后,对状态代码或HTTP标头所做的任何更改都不会产生任何影响。

您可以尝试使用OWIN提供的OnSendingHeaders回调。使用方法如下:

public override async Task Invoke(IOwinContext context)
{
   var response = context.Response;
   var request =  context.Request;

   response.OnSendingHeaders(state =>
   {
       var resp = (OwinResponse)state;
       resp.Headers.Add("X-MyResponse-Header", "Some Value");
       resp.StatusCode = 403;
       resp.ReasonPhrase = "Forbidden";
    }, response);

  var header = request.Headers["X-Whatever-Header"];

  await Next.Invoke(context);
}

感谢biscuit314更新我的答案。