C# asp.net web api中的异常处理和日志记录
我是ASP.NETWebAPI新手,我正在阅读这两篇关于异常处理的文章 虽然我了解链接,但我不确定是否使用。以下是我想做的:C# asp.net web api中的异常处理和日志记录,c#,asp.net,asp.net-web-api,C#,Asp.net,Asp.net Web Api,我是ASP.NETWebAPI新手,我正在阅读这两篇关于异常处理的文章 虽然我了解链接,但我不确定是否使用。以下是我想做的: 当发生错误时,我想用消息、堆栈跟踪和原始请求发送的请求对象记录该错误 每个传入请求的类型可能不同&我计划将请求对象序列化为JSON字符串,并在错误日志记录时将其存储在DB中 似乎我应该在每个方法上添加try-catch块,然后执行异常处理和日志记录。这将是一项乏味的任务。是否有任何方法可以全局处理错误并仍然能够捕获异常详细信息(消息、堆栈跟踪)和日志请求对象。创建一个
似乎我应该在每个方法上添加try-catch块,然后执行异常处理和日志记录。这将是一项乏味的任务。是否有任何方法可以全局处理错误并仍然能够捕获异常详细信息(消息、堆栈跟踪)和日志请求对象。创建一个筛选器来为您处理这些操作,然后全局注册筛选器。我们做了一些非常相似的事情,下面是我们使用的过滤器类
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());
}
}
}
是否有任何方法可以全局处理错误并仍然能够捕获错误
异常详细信息(消息、堆栈跟踪)和日志请求对象
是的,ASP.NET Web API 2.1的框架支持全局处理未处理的异常,而不是在每个方法上添加try-catch块
它允许用户自定义在发生未处理的应用程序异常时发送的HTTP响应
WebApiConfig
GlobalExceptionHandler
自定义错误结果
公共类CustomErrorResult:IHttpActionResult
{
私有只读字符串\u errorMessage;
私有只读HttpRequestMessage\u requestMessage;
私有只读HttpStatusCode\u statusCode;
public CustomErrorResult(HttpRequestMessage requestMessage,
HttpStatusCode状态代码,字符串错误消息)
{
_requestMessage=requestMessage;
_statusCode=statusCode;
_errorMessage=errorMessage;
}
公共任务执行同步(
取消令牌(取消令牌)
{
返回Task.FromResult(_requestMessage.CreateErrorResponse(
_状态代码,_errorMessage));
}
}
要归功于阅读web api中的交叉关注点。您的控制器操作应尽可能精简。您不了解的错误处理链接是什么?那篇文章回答了这个问题。。。
config.Filters.Add(new FailedApiRequestLoggerAttribute(true));
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// ...
config.Services.Replace(typeof (IExceptionHandler),
new GlobalExceptionHandler());
}
}
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);
}
}
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));
}
}