Ope*_*ack 4 c# asp.net asp.net-web-api
我是 ASP.NET web api 的新手,我正在阅读这两篇关于异常处理的文章
虽然我了解异常处理链接,但我不确定是否使用 错误处理。这是我想要做的:
似乎我应该在每个方法上添加 try catch 块,然后执行异常处理和日志记录。这将是一项乏味的任务。有没有办法全局处理错误并且仍然能够捕获异常详细信息(消息、堆栈跟踪)和日志请求对象。
有没有办法全局处理错误并且仍然能够捕获异常详细信息(消息、堆栈跟踪)和日志请求对象。
是的,ASP.NET Web API 2.1 具有对未处理异常的全局处理的框架支持,而不是在每个方法上添加 try catch 块。
它允许自定义发生未处理的应用程序异常时发送的 HTTP 响应。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// ...
config.Services.Replace(typeof (IExceptionHandler),
new GlobalExceptionHandler());
}
}
Run Code Online (Sandbox Code Playgroud)
public class GlobalExceptionHandler : ExceptionHandler
{
public override void Handle(ExceptionHandlerContext context)
{
var exception = context.Exception;
var httpException = exception as HttpException;
if (httpException != null)
{
context.Result = new CustomErrorResult(context.Request,
(HttpStatusCode) httpException.GetHttpCode(),
httpException.Message);
return;
}
// Return HttpStatusCode for other types of exception.
context.Result = new CustomErrorResult(context.Request,
HttpStatusCode.InternalServerError,
exception.Message);
}
}
Run Code Online (Sandbox Code Playgroud)
public class CustomErrorResult : IHttpActionResult
{
private readonly string _errorMessage;
private readonly HttpRequestMessage _requestMessage;
private readonly HttpStatusCode _statusCode;
public CustomErrorResult(HttpRequestMessage requestMessage,
HttpStatusCode statusCode, string errorMessage)
{
_requestMessage = requestMessage;
_statusCode = statusCode;
_errorMessage = errorMessage;
}
public Task<HttpResponseMessage> ExecuteAsync(
CancellationToken cancellationToken)
{
return Task.FromResult(_requestMessage.CreateErrorResponse(
_statusCode, _errorMessage));
}
}
Run Code Online (Sandbox Code Playgroud)
归功于ASP.NET Web API 2:从头到尾构建 REST 服务
创建一个过滤器来为您处理这些操作,然后全局注册该过滤器。我们做了一些非常相似的事情,这是我们使用的过滤器类。
public class FailedApiRequestLoggerAttribute : ActionFilterAttribute
{
private readonly bool _removeErrorDetailsFromResponse;
public FailedApiRequestLoggerAttribute(bool removeErrorDetailsFromResponse)
{ _removeErrorDetailsFromResponse = removeErrorDetailsFromResponse; }
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
var log = LoggerFactory.GetLogger(actionExecutedContext.ActionContext.ControllerContext.Controller.GetType().Name);
// If there is no response object then we're probably here because an exception was
// thrown and thrown exceptions are handled elsewhere.
if (actionExecutedContext.Response?.IsSuccessStatusCode == false)
{
var error = new StringBuilder();
error.AppendLine("API Call Returned Non-Success Status");
error.AppendLine($"{actionExecutedContext.ActionContext.ControllerContext.ControllerDescriptor.ControllerType.FullName}.{actionExecutedContext.ActionContext.ActionDescriptor.ActionName}");
if (actionExecutedContext.ActionContext.ActionArguments.Any())
{ error.AppendLine($" Arguments"); }
foreach (var argument in actionExecutedContext.ActionContext.ActionArguments)
{ error.AppendLine($" {JsonConvert.SerializeObject(argument)}"); }
error.AppendLine(" Response");
error.AppendLine($" Status Code: {actionExecutedContext.Response.StatusCode}; Reason: {actionExecutedContext.Response.ReasonPhrase}");
var content = actionExecutedContext.Response.Content as ObjectContent<HttpError>;
if (content != null)
{
error.AppendLine($" {JsonConvert.SerializeObject(content.Value)}");
if (_removeErrorDetailsFromResponse)
{ ((HttpError)content.Value).Clear(); }
}
log.Warning(error.ToString());
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后它在全球范围内注册。
config.Filters.Add(new FailedApiRequestLoggerAttribute(true));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11572 次 |
| 最近记录: |