我的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;
}
}
问题:
是从中得出的推荐做法OwinMiddleware
吗?我在Katana源代码中看到,一些中间件类是从中派生的,OwinMiddleware
而有些则不是。
我可以看到请求标头。Next.Invoke
在我的中间件中设置响应标头或状态代码对返回给客户端的响应没有影响。但是,如果我在Next.Invoke
调用之前设置了响应标头或状态,则带有标头和我设置的状态的响应将返回给客户端。设置这些的正确方法是什么?
是的,建议从OwinMiddleware派生。某些中间件类之所以不能从OwinMiddleware派生,是因为它们是最近才引入的,所以它们尚未切换。或者为避免由于某种原因使程序集依赖于Microsoft.Owin程序集。
在调用“在下一步上调用”后,在响应上设置内容的可能原因不起作用,因为一旦有人开始写入响应主体流,就会立即发送响应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更新我的答案。
谢谢优素福。对于第2点,从最佳实践角度来看,在Katana源代码中或我可以查看的其他地方是否有示例代码?我相信,我要问的是一个相当普遍的需求,如果我们使用OWIN中间件,是否每个人都应该进行此流切换只是为了设置响应头?任何指针将不胜感激。
我可以按照您的建议解决问题,但是没有简单的出路吗?我的意思是,仅在出局时设置响应标头就需要太多工作,尤其是如果一个标头用于Web API的消息处理程序时。
用更简单的方法更新了答案。请让我知道它是否有效。
“是的,建议从OwinMiddleware派生。” 不,不,不是。github.com/owin/owin/issues/20 github.com/owin/owin/issues/19
@ Valipour,OnSendingHeaders回调仅在开始在网络上发送数据后才运行,因此您应该能够在此时检查响应