从OWIN Middleware更改响应对象

Bad*_*dri 28 c# asp.net-web-api owin katana

我的OWIN中间件是这样的.(Framework是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;

    }
}
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 是推荐的做法来源于OwinMiddleware?我看到在Katana源代码中,一些中间件类来自OwinMiddleware,有些则不是.

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

You*_*oui 29

  1. 是的,推荐使用OwinMiddleware.一些中间件类不是从OwinMiddleware派生的原因是它们要么尚未切换,因为最近引入了类.或者为了避免程序集因某种原因依赖于Microsoft.Owin程序集.

  2. 调用Next上的Invoke之后在响应上设置内容的可能原因是,只要有人开始写入响应正文流,就会发送响应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);
}
Run Code Online (Sandbox Code Playgroud)

感谢biscuit314更新我的回答.

  • "是的,推荐使用OwinMiddleware." 不,不,不是.https://github.com/owin/owin/issues/20 https://github.com/owin/owin/issues/19 (9认同)
  • 使用更简单的方法更新了答案.如果有效,请告诉我. (3认同)

bis*_*314 10

我试图编辑优素福的优秀答案,以纠正一个小错误,并用OwinMiddleware现在的工作方式更新示例.

编辑被拒绝了(好吧,一个人批准,一个人因为太小而被拒绝,两个因为太大而被拒绝).

这是Youssef代码的那个版本:

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"; // if you're going to change the status code
                                         // you probably should also change the reason phrase
    }, response);

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

  await Next.Invoke(context);
}
Run Code Online (Sandbox Code Playgroud)