C# 登录中间件异常处理程序

C# 登录中间件异常处理程序,c#,exception,.net-core,C#,Exception,.net Core,在分层web应用程序中,我希望将所有错误日志记录从域和数据层移动到全局异常处理程序,但我不确定如何权衡。我想删除任何日志调用,并将其替换为更具体的异常(如有必要,可自定义)或删除捕获: try{ . . . } catch { Logger.Error('Info'); // <-- remove this for a: throw new CustomException('Info', ex); throw; // <-- then

在分层web应用程序中,我希望将所有错误日志记录从域和数据层移动到全局异常处理程序,但我不确定如何权衡。我想删除任何日志调用,并将其替换为更具体的异常(如有必要,可自定义)或删除捕获:

try{
   . . . 
}
catch
{
   Logger.Error('Info'); // <-- remove this for a: throw new CustomException('Info', ex);
   throw;                // <-- then, remove this line
}

是避免重复日志记录的更好方法吗?

在我构建的应用程序中,我喜欢使用您建议的方法。我将发布我使用的中间件:

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using MyProject.Interfaces;

namespace MyProject.Middlewares
{
    public class ErrorReporterMiddleware
    {
        private readonly RequestDelegate RequestDelegate;

        public ErrorReporterMiddleware(RequestDelegate requestDelegate)
        {
            RequestDelegate = requestDelegate ?? throw new ArgumentNullException(nameof(requestDelegate));
        }

        public async Task Invoke(HttpContext httpContext, IErrorReporter errorReporter)
        {
            try
            {
                await RequestDelegate(httpContext);
            }
            catch (Exception e)
            {
                await errorReporter?.CaptureAsync(e);
                throw;
            }
        }
    }
}
在本例中,
IErrorReporter
是我在
MyProject.Interfaces
命名空间中定义的一个接口。我使用它来抽象日志记录服务:

using System;
using System.Threading.Tasks;

namespace MyProject.Interfaces
{
    public interface IErrorReporter
    {
        Task CaptureAsync(Exception exception);
        Task CaptureAsync(string message);
    }
}
然后在
Startup.cs
中,我只需在
Configure
方法中添加以下行:

app.UseMiddleware<ErrorReporterMiddleware>();
app.UseMiddleware();

没有什么特别之处,但我认为这是一种干净的方法。

将异常日志从类中移出并转移到中间件或拦截器中是一种很好的做法。如果一个方法捕获一个异常,记录它,然后重新引用它,那么AOP方法允许您消除所有这些try/catch,并让类之外的东西来处理它。偶尔,您可能仍然需要在类中进行日志记录,就像在类实际处理异常并对其进行解释的场景中一样,但是您仍然需要记录一些内容,以便知道异常发生了。
app.UseMiddleware<ErrorReporterMiddleware>();