无法在Core管道

时间:2018-01-10 17:43:59

标签: c# asp.net-core .net-core middleware

我已经在我的 Startup 类中添加了一个自定义中间件(在示例here之后)。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
  app.Use((context, next) =>
  {
    try { return next(); }
    catch (Exception exception) { return new Task(() => { }); }
  });

  app.UseCors("Welcome All");
  app.UseMvc();
  app.UseSwagger();
  app.UseSwaggerUI(_ => _.SwaggerEndpoint("/swagger/v0.1/swagger.json", "Version 0.1"));
}

我的理解是在控制器中的方法中抛出异常应该在自定义中间件的 try-catch 中捕获。但.NET Core似乎对我的期望有所怀疑。通过断点,我可以看到 return next()在控制器的方法抛出异常后被调用但是,异常没有被捕获,黄色标记跳过中间件alltoghether并落在它的最后一个大括号。

我缺少什么?

如果它有任何意义或兴趣,我的目标是将我的方法中的异常处理移出到orde中的横切中间以简化代码(我不想应用过滤器,因为我的目标是纯粹的WebApi没有MVC)。所以控制器和方法看起来像这样。

[Route("api/test")]
public class TestController : Controller
{
  public TestController(...) { ... }
  ...
  [HttpPost]
  public IActionResult CrashBoom([FromBody] Thing input)
  {
    if (input.isCrashworthy)
      throw new Exception("Boom")
    else
      return Ok();
  }
}

1 个答案:

答案 0 :(得分:3)

这里的问题是请求委托,中间件的可执行部分,异步运行。如果你查看next的类型,你可以看到它实际上是Func<Task>,所以它是一个返回任务的函数。或者换句话说:它是一个没有返回值的异步函数。

这意味着为了能够捕获异常,您需要保留异步上下文。因此,您的自定义中间件也应该异步执行。如果你这样做,你会注意到你可以捕获异常然后相应地回复它们,例如通过写出纯文本响应(作为例子):

app.Use(async (context, next) =>
{
    try
    {
        await next();
    }
    catch (Exception ex)
    {
        // let’s log the exception
        var logger = context.RequestServices.GetService<ILogger<Startup>>();
        logger.LogWarning(ex, "Encountered an exception");

        // write a response
        context.Response.StatusCode = 500;
        context.Response.ContentType = "text/plain";
        await context.Response.WriteAsync("Sorry, something went wrong!");
    }
});

现在,如果在中间件管道中进一步引发异常,那么您的自定义管道将能够捕获并响应它。