从OWIN Middleware更改响应对象

我的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; } } 

问题:

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

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

  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); } 

感谢biscuit314更新我的回答。

我试图编辑Youssef的优秀答案来纠正一个小错误,并用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); }