ASP.NET 5中间件"没有收到响应"添加标题后

时间:2015-10-01 11:15:42

标签: asp.net asp.net-web-api asp.net-core

public class MyMiddleware
{
    RequestDelegate _next;

    public MyMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {

        //await context.Response.WriteAsync("Hello!");
        await _next(context);
        context.Response.Headers.Add("X-ElapsedTime", new[] { "bla" });
    }
}

只要我添加标题之类的东西。我的Web API控制器无法再收到任何响应。

 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
 {
     app.UseMyMiddleware();
     app.UseMvc();
 }

我是否需要首先阅读以下中间件的答案" UseMvc"产生

我只有一个非常简单的Controller方法:

    // GET: api/values
    [HttpGet]
    public IEnumerable<string> Get()
    {
        //Task t = new Task(() => Thread.Sleep(2000));
        //t.Start();

        return new string[] { "value1", "value2" };
    }

我认为我找到了一个解决方案,但实际上并不是一个完整的答案:

 public class MyMiddleware
{
    RequestDelegate _next;
    HttpContext _context;

    public MyMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task Invoke(HttpContext context)
    {
        _context = context;
        context.Response.OnStarting(OnStartingCallback, state: this);
        await _next(context);
    }
    public Task OnStartingCallback(object state)
    {
        _context.Response.Headers.Set("x-bla", "bla");
        return Task.FromResult(0);
    }
}

我找到了对https://github.com/aspnet/Session/blob/master/src/Microsoft.AspNet.Session/SessionMiddleware.cs的引用,并尝试根据它构建我的代码。

无论如何,这段代码感觉不太安全。它真的是线程安全吗。

1 个答案:

答案 0 :(得分:1)

基本上发生的事情是,在将任何内容写入响应正文后,您无法设置任何标题。

这是因为标题是在正文之前以及设置任何正文内容时发送的。

以适当的方式绕过它将缓冲响应并且不发送任何内容,直到所有中间件都已被执行,因此他们有机会修改标头。此行为应该是Web服务器的责任。不幸的是,我没有找到任何有用的信息如何在ASP.NET 5(IIS或Kestrel)上配置缓冲。

您的解决方案似乎没问题,但它线程安全。中间件是单例,在类字段中保存上下文可能会在多个并发请求可能会命中您的服务器时引入竞争条件。 您可以通过将上下文作为状态对象传递来使其成为线程安全的。

context.Response.OnStarting(OnStartingCallback, state: context);

然后将object state投射到HttpContext

,在回调中检索它