2017-09-21 31 views
0

下面是我的实现。我写了一个CustomExceptionFilterAttribute,它从ExceptionFilterAttribute继承。每个错误都放在一个if和else中以产生正确的结果。我想要做的是创建一个回调函数,以便我可以删除if和else块和错误可以更通用的方式处理。在asp.net核心2.0中编写一个通用的ExceptionFitler

public class HostedServicesController : BaseController 
{ 
    public IActioResult Index() 
    { 
     throw new NotFoundInDatabaseException("Error in Index Controller"); 
    } 
} 

public class NotFoundInDatabaseException : Exception 
{ 
    public NotFoundInDatabaseException(string objectName, object objectId) : 
      base(message: $"No {objectName} with id '{objectId}' was found") 
     { 

     } 
} 

public class CustomExceptionFilterAttribute :ExceptionFilterAttribute 
    { 
     private SystemManager SysMgr { get; } 

     public CustomExceptionFilterAttribute(SystemManager systemManager) 
     { 
      SysMgr = systemManager; 
     } 
     public override void OnException(ExceptionContext context) 
     { 
      var le = SysMgr.Logger.NewEntry(); 
      try 
      { 
       le.Message = context.Exception.Message; 
       le.AddException(context.Exception); 

       var exception = context.Exception; 
       if (exception is NotFoundInDatabaseException) 
       { 
        le.Type = LogType.ClientFaultMinor; 
        context.Result = new NotFoundObjectResult(new Error(ExceptionCode.ResourceNotFound, exception.Message)); 
       } 
       else if (exception is ConfigurationException) 
       { 
        le.Type = LogType.ErrorMinor; 
        context.Result = new BadRequestObjectResult(new Error(ExceptionCode.NotAuthorised, exception.Message)); 
       } 
       else 
       { 
        le.Type = LogType.ErrorSevere; 
        context.Result = new InternalServerErrorObjectResult(new Error(ExceptionCode.Unknown, exception.Message)); 
       } 
       le.AddProperty("context.Result", context.Result); 
       //base.OnException(context); 
      } 
      finally 
      { 
       Task.Run(() => SysMgr.Logger.LogAsync(le)).Wait(); 
      } 
     } 
    } 

回答

0

您可以使用一个Dictionary与一个自定义类型为此。想想这样的事情:

public class ErrorHandlerData 
{ 
    public LogType LogType { get; set; } 
    public string ExceptionCode { get; set; } // not sure if string 
} 

public class CustomExceptionFilterAttribute :ExceptionFilterAttribute 
{ 
    private static Dictionary<Type, ErrorHandlerData> MyDictionary = new Dictionary<Type, ErrorHandlerData>(); 

    static CustomExceptionFilterAttribute() 
    { 
     MyDictionary.Add(typeof(NotFoundInDatabaseException), new ErrorHandlerData 
      { 
       LogType = LogType.ClientFaultMinor, 
       ExceptionCode = ExceptionCode.ResourceNotFound 
      }; 

      //general catch-all 
     MyDictionary.Add(typeof(Exception), new ErrorHandlerData 
      { 
       LogType = LogType.ErrorSevere, 
       ExceptionCode = ExceptionCode.Unknown 
      }; 
    } 

所以,你可以使用它像这样:

public override void OnException(ExceptionContext context) 
{ 
    var le = SysMgr.Logger.NewEntry(); 
    try 
    { 
     le.Message = context.Exception.Message; 
     le.AddException(context.Exception); 

     var exception = context.Exception; 
     var exeptionType = exception.GetType(); 
     var errorHandlerData = MyDictionary.ContainsKey(exceptionType) ? 
      MyDictionary[exceptionType] : MyDictionary[typeof(Exception)]; 

     le.Type = errorHandlerData.LogType; 
     context.Result = new NotFoundObjectResult(new Error(errorHandlerData.ExceptionCode, exception.Message)); 

     le.AddProperty("context.Result", context.Result); 
    } 
    finally 
    { 
     Task.Run(() => SysMgr.Logger.LogAsync(le)).Wait(); 
    } 
}