C# 如何在.NETCore中创建自定义异常和错误处理程序?

C# 如何在.NETCore中创建自定义异常和错误处理程序?,c#,asp.net,angular,C#,Asp.net,Angular,我使用C#开发了一个.NETCore3RESTAPI 我读了很多关于这个主题的书,并且实现了一个定制的异常处理中间件,它工作得很好 但我意识到错误消息的结构不同 例如,我使用.Net Core Identity,当我尝试保存一个已经保存的用户名时,我会得到一个HTTP 400,错误响应如下:(很抱歉,我无法发布图像。) 我还使用了属性验证,它给出了HTTPErrorResponse: error: { . . . errors:{ Password: Array(1) {

我使用C#开发了一个.NETCore3RESTAPI

我读了很多关于这个主题的书,并且实现了一个定制的异常处理中间件,它工作得很好

但我意识到错误消息的结构不同

例如,我使用.Net Core Identity,当我尝试保存一个已经保存的用户名时,我会得到一个HTTP 400,错误响应如下:(很抱歉,我无法发布图像。)

我还使用了属性验证,它给出了HTTPErrorResponse:

error: {
  .
  .
  .
  errors:{
    Password: Array(1) {
      0: "The field..."
    }
  }
}
最后,我的自定义异常处理程序类给出了一个ErroDTO,其中包含一个代码和一个描述

所以问题是有三种情况,它们给出了三种不同的错误响应,我不知道如何处理,在前端,这是一个角度项目

我想通过ErroDto类处理所有错误和异常,但我不知道如何转换标识或属性错误

我认为我可以直接在端点中测试电子邮件和密码验证,而不是使用属性,并且我可以测试现有电子邮件是否正确,并且不会抛出错误。但我认为这不是最佳实践,而且会有很多样板代码

这是我的异常处理类:

public class ErrorHandlingMiddleware
    {
        private readonly RequestDelegate next;
        public ErrorHandlingMiddleware(RequestDelegate next)
        {
            this.next = next;
        }

        public async Task Invoke(HttpContext context /* other dependencies */)
        {
            try
            {
                await next(context);
            }
            catch (Exception ex)
            {
                await HandleExceptionAsync(context, ex);
            }
        }

        private static Task HandleExceptionAsync(HttpContext context, Exception ex)
        {
            var code = HttpStatusCode.InternalServerError; // 500 if unexpected

            ErrorDto error = new ErrorDto();

            if (ex is WrongCredentialsException)
            {
                code = HttpStatusCode.OK;

                WrongCredentialsException wrongCredentialsException = (WrongCredentialsException) ex;

                error.Code = wrongCredentialsException.Code;
                error.Description = wrongCredentialsException.Message;
            }

            var result = JsonConvert.SerializeObject(new { error });


            context.Response.ContentType = "application/json";
            context.Response.StatusCode = (int)code;
            return context.Response.WriteAsync(result);
        }
    }
  • 创建自定义异常类
使用系统;
[可序列化]
公共类EmployeeMgmtException:异常
{
公共EmployeeMgmtException(字符串消息):基本(消息)
{
}
}    
  • 创建一个异常中间件类
公共类例外中间件
{    
私有只读请求委托下一步;
专用只读ILogger记录器;
私有只读ResourceManager ResourceManager;
}    
公共例外中间件(RequestDelegate next,ILogger
记录器)
{
this.next=next;
this.logger=记录器;
this.resourceManager=new
ResourceManager(“EmployeeException.API.Resources.Resource”,
类型(中间件除外)。组件);
}   
公共异步任务InvokeAsync(HttpContext HttpContext)
{
尝试
{
等待this.next.Invoke(httpContext);
}
捕获(例外情况除外)
{
等待这个.HandleExceptionAsync(httpContext,ex);
}
}
私有任务HandleExceptionAsync(HttpContext上下文,异常)
{
context.Response.ContentType=“应用程序/json”;
ErrorResponse=新的ErrorResponse();
如果(例外情况为EmployeeMgmtException)
{
context.Response.StatusCode=(int)HttpStatusCode.OK;
response.ErrorMessage=异常.Message;
}
其他的
{
context.Response.StatusCode=(int)HttpStatusCode.InternalServerError;
response.ErrorMessage=this.resourceManager.GetString(“FailedToProcess”,
文化信息(CURRENTUICURRENT);
}
LogCritical(异常、异常、消息、GetProperties(上下文));
返回context.Response.WriteAsync(Response.ToString());
}
}    
  • 在Startup.cs中注册异常中间件筛选器
app.UseMiddleware();

只需定制某种类型的
ErrorClass
。然后,创建重载或其他能够将您处理的任何其他错误对象映射到自定义类的东西。是的,我考虑过,但我不知道如何捕获标识和属性的所有错误。你能给我一些想法吗?
public class ErrorHandlingMiddleware
    {
        private readonly RequestDelegate next;
        public ErrorHandlingMiddleware(RequestDelegate next)
        {
            this.next = next;
        }

        public async Task Invoke(HttpContext context /* other dependencies */)
        {
            try
            {
                await next(context);
            }
            catch (Exception ex)
            {
                await HandleExceptionAsync(context, ex);
            }
        }

        private static Task HandleExceptionAsync(HttpContext context, Exception ex)
        {
            var code = HttpStatusCode.InternalServerError; // 500 if unexpected

            ErrorDto error = new ErrorDto();

            if (ex is WrongCredentialsException)
            {
                code = HttpStatusCode.OK;

                WrongCredentialsException wrongCredentialsException = (WrongCredentialsException) ex;

                error.Code = wrongCredentialsException.Code;
                error.Description = wrongCredentialsException.Message;
            }

            var result = JsonConvert.SerializeObject(new { error });


            context.Response.ContentType = "application/json";
            context.Response.StatusCode = (int)code;
            return context.Response.WriteAsync(result);
        }
    }