栈,
由于某些原因,我的Owin WebApi服务忽略了我们的自定义异常处理程序。我正在关注asp.net exception handling的文档。以下是简化的实现细节(清除了业务专有的东西)。
你能指出我在忽视的东西吗?
自定义例外过滤器:
public class CustomExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
actionExecutedContext.Response.StatusCode = HttpStatusCode.NotFound;
actionExecutedContext.Response.Content = new StringContent("...my custom business...message...here...");
}
}
启动期间:
var filter = new CustomExceptionFilter();
config.Filters.Add(filter);
appBuilder.UseWebApi(config);
测试控制器:
[CustomExceptionFilter]
public class TestController: ApiController
{
public void Get()
{
throw new Exception(); // This is a simplification.
// This is really thrown in buried
// under layers of implementation details
// used by the controller.
}
}
答案 0 :(得分:3)
您可以尝试实施Global Error Handling in ASP.NET Web API 2。 这样,您将获得Web API中间件的全局错误处理程序,但不会获得OWIN pippeline中的其他中间件,例如授权中间件。
如果您想实现全局错误处理中间件,this,this和this链接可以为您定位。
我希望它有所帮助。
修改强>
关于@ t0mm13b的评论,我会根据this的第一个Khanh TO链接给出一些解释。
对于全局错误处理,您可以编写一个自定义且简单的中间件,它只是将执行流程传递给管道中但在try
块内的以下中间件。
如果管道中的以下某个中间件存在未处理的异常,则会在catch
块中捕获:
public class GlobalExceptionMiddleware : OwinMiddleware
{
public GlobalExceptionMiddleware(OwinMiddleware next) : base(next)
{ }
public override async Task Invoke(IOwinContext context)
{
try
{
await Next.Invoke(context);
}
catch (Exception ex)
{
// your handling logic
}
}
}
在Startup.Configuration()
方法中,如果要处理所有其他中间件的异常,请将中间件首先添加到管道中。
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use<GlobalExceptionMiddleware>();
//Register other middlewares
}
}
正如第二个{{3}}链接中的Tomas Lycken指出的那样,您可以使用它来处理Web API中间件中生成的异常,从而创建一个实现IExceptionHandler
的类,只抛出捕获的异常,这样,全局异常处理程序中间件将捕获它:
public class PassthroughExceptionHandler : IExceptionHandler
{
public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
{
// don't just throw the exception; that will ruin the stack trace
var info = ExceptionDispatchInfo.Capture(context.Exception);
info.Throw();
}
}
并且不要忘记在Web API中间件配置期间替换IExceptionHandler
:
config.Services.Replace(typeof(IExceptionHandler), new PassthroughExceptionHandler());