我如何要求Owin / Katana将标头写入输出流?

当我写回复时,Katana会跳过发送Elapsed-Time响应头。 在我第一次写入流之前,如何让它为我设置标题?

中间件#1

public override async Task Invoke(IOwinContext context) { var stopwatch = new Stopwatch(); stopwatch.Start(); await Next.Invoke(context); stopwatch.Stop(); context.Response.Headers.Add("Elapsed-Time", new[] {stopwatch.ElapsedMilliseconds.ToString()}); } 

中间件#2

  public override async Task Invoke(IOwinContext context) { await context.Response.WriteAsync("test"); } 

经过一些研究,答案是设置标题需要在OnSendingHeaders中发生。 这可确保在写入输出流之前设置标头。 例如:

  public override async Task Invoke(IOwinContext context) { var stopwatch = new Stopwatch(); context.Response.OnSendingHeaders(x => { stopwatch.Stop(); context.Response.Headers.Add("X-Processing-Time", new[] {stopwatch.ElapsedMilliseconds.ToString()}); }, null); stopwatch.Start(); await Next.Invoke(context); stopwatch.Stop(); } 

使用ResponseHeaders属性。

 public override async Task Invoke(IOwinContext context) { context.Response.Headers.Add("Content-Length", ); await context.Response.WriteAsync("test"); } 

UPDATE

您的中间件看起来是正确的。 也许,您在配置中遇到问题。

检查,如果你已经像这样管道你的中间线:

 app.Use(typeof(MiddlewareOne)) .Use(typeof(MiddlewareTwo)); 

顺便说一句,你不需要两个midlewares。 这将作为墙:

 public class MyMiddleware : OwinMiddleware { public MyMiddleware(OwinMiddleware next) : base(next) {} public override async Task Invoke(IOwinContext context) { var stopwatch = new Stopwatch(); stopwatch.Start(); await context.Response.WriteAsync("test"); stopwatch.Stop(); context.Response.Headers.Add("Elapsed-Time", new[] {stopwatch.ElapsedMilliseconds.ToString()}); } } 

和配置是:

 app.Use(typeof(MyMiddleware));