Joe*_*ley 112 c# unhandled-exception asp.net-web-api
如何捕获ASP.NET Web Api中发生的所有未处理的异常,以便我可以记录它们?
到目前为止,我尝试过:
ExceptionHandlingAttributeApplication_Error方法Global.asax.csAppDomain.CurrentDomain.UnhandledExceptionTaskScheduler.UnobservedTaskException在ExceptionHandlingAttribute成功处理时引发的控制器操作方法和操作筛选范围内,但其他异常没有被处理,例如例外:
IQueryableaction方法返回的异常无法执行时抛出的异常HttpConfiguration.MessageHandlers)基本上,如果异常将导致500内部服务器错误返回到客户端,我希望它被记录.实现Application_Error在Web窗体和MVC中完成了这项工作 - 我可以在Web Api中使用什么?
dec*_*tes 155
现在可以使用WebAPI 2.1(参见新功能):
创建IExceptionLogger的一个或多个实现.例如:
public class TraceExceptionLogger : ExceptionLogger
{
public override void Log(ExceptionLoggerContext context)
{
Trace.TraceError(context.ExceptionContext.Exception.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
然后在配置回调中注册您的应用程序的HttpConfiguration,如下所示:
config.Services.Add(typeof(IExceptionLogger), new TraceExceptionLogger());
Run Code Online (Sandbox Code Playgroud)
或直接:
GlobalConfiguration.Configuration.Services.Add(typeof(IExceptionLogger), new TraceExceptionLogger());
Run Code Online (Sandbox Code Playgroud)
Duo*_*ran 20
Yuval的答案是自定义对Web API捕获的未处理异常的响应,而不是用于记录,如链接页面上所述.有关详细信息,请参阅页面上的"何时使用"部分.始终调用记录器,但只有在可以发送响应时才调用处理程序.简而言之,使用记录器记录和处理程序来自定义响应.
顺便说一句,我正在使用程序集v5.2.3,并且ExceptionHandler该类没有该HandleCore方法.我认为相当于Handle.但是,简单地进行子类化ExceptionHandler(如Yuval的答案)是行不通的.在我的情况下,我必须实现IExceptionHandler如下.
internal class OopsExceptionHandler : IExceptionHandler
{
private readonly IExceptionHandler _innerHandler;
public OopsExceptionHandler (IExceptionHandler innerHandler)
{
if (innerHandler == null)
throw new ArgumentNullException(nameof(innerHandler));
_innerHandler = innerHandler;
}
public IExceptionHandler InnerHandler
{
get { return _innerHandler; }
}
public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
{
Handle(context);
return Task.FromResult<object>(null);
}
public void Handle(ExceptionHandlerContext context)
{
// Create your own custom result here...
// In dev, you might want to null out the result
// to display the YSOD.
// context.Result = null;
context.Result = new InternalServerErrorResult(context.Request);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,与记录器不同,您通过替换默认处理程序而不是添加来注册处理程序.
config.Services.Replace(typeof(IExceptionHandler),
new OopsExceptionHandler(config.Services.GetExceptionHandler()));
Run Code Online (Sandbox Code Playgroud)
Joe*_*ley 18
要回答我自己的问题,这是不可能的!
处理导致内部服务器错误的所有异常似乎是Web API应具备的基本功能,因此我向Microsoft提出了针对Web API的全局错误处理程序的请求:
https://aspnetwebstack.codeplex.com/workitem/1001
如果您同意,请转到该链接并投票支持!
与此同时,优秀的文章ASP.NET Web API异常处理显示了几种不同的方法来捕获几个不同类别的错误.它比它应该更复杂,并且它不能捕获所有内部服务器错误,但它是当今可用的最佳方法.
更新:全局错误处理现已实施,并可在夜间构建中使用!它将在ASP.NET MVC v5.1中发布.以下是它的工作原理:https://aspnetwebstack.codeplex.com/wikipage?title = Global%20Error%20Handling
您还可以通过实现IExceptionHandler接口(或继承ExceptionHandler基类)来创建全局异常处理程序.在所有注册后,它将是执行链中最后一个被调用的IExceptionLogger:
IExceptionHandler处理来自所有控制器的所有未处理的异常.这是列表中的最后一个.如果发生异常,将首先调用IExceptionLogger,然后调用控制器ExceptionFilters,如果仍未处理,则调用IExceptionHandler实现.
public class OopsExceptionHandler : ExceptionHandler
{
public override void HandleCore(ExceptionHandlerContext context)
{
context.Result = new TextPlainErrorResult
{
Request = context.ExceptionContext.Request,
Content = "Oops! Sorry! Something went wrong."
};
}
private class TextPlainErrorResult : IHttpActionResult
{
public HttpRequestMessage Request { get; set; }
public string Content { get; set; }
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
HttpResponseMessage response =
new HttpResponseMessage(HttpStatusCode.InternalServerError);
response.Content = new StringContent(Content);
response.RequestMessage = Request;
return Task.FromResult(response);
}
}
}
Run Code Online (Sandbox Code Playgroud)
更多关于这一点.
| 归档时间: |
|
| 查看次数: |
55566 次 |
| 最近记录: |