Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# asp.net web api中的异常处理和日志记录_C#_Asp.net_Asp.net Web Api - Fatal编程技术网

C# asp.net web api中的异常处理和日志记录

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块,然后执行异常处理和日志记录。这将是一项乏味的任务。是否有任何方法可以全局处理错误并仍然能够捕获异常详细信息(消息、堆栈跟踪)和日志请求对象。创建一个

我是ASP.NETWebAPI新手,我正在阅读这两篇关于异常处理的文章

  • 虽然我了解链接,但我不确定是否使用。以下是我想做的:

  • 当发生错误时,我想用消息、堆栈跟踪和原始请求发送的请求对象记录该错误
  • 每个传入请求的类型可能不同&我计划将请求对象序列化为JSON字符串,并在错误日志记录时将其存储在DB中
    似乎我应该在每个方法上添加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));
        }
    }