ASP.NET C# Catch all exceptions in a class

前端 未结 5 691
我在风中等你
我在风中等你 2021-01-30 12:05

I know this is not the way to do it, and it isn\'t clean at all. I just wonder if it\'s possible.

If I have a class with a bunch of methods

public class          


        
5条回答
  •  后悔当初
    2021-01-30 12:11

    Yes it is. The simplest way would be a Attribute for this class like this one:

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class HandleErrorAttribute : FilterAttribute, IExceptionFilter
    {
    
        public void OnException(ExceptionContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }
    
            if (filterContext.ExceptionHandled)
            {
                return;
            }
    
            var exception = filterContext.Exception;
    
            // that need to be your current request object. In this case I use a custom one so I must fetch it from the items collection of the current request, where I had stored it before.
            var request = filterContext.HttpContext.Items[Request.RequestKey] as Request;
    
            if (request != null)
            {
                // overwrite ErrorResponse with a response object of your choice or write directly to the filterContext.HttpContext.Response
                var errorResponse = new ErrorResponse(request, exception); 
                errorResponse.Write(filterContext.HttpContext.Response);
                filterContext.ExceptionHandled = true;
            }
        }
    }
    
    // Or a just slightly modified version of the default ASP.Net MVC HandleError Attribute
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
        public class CustomHandleErrorAttribute : FilterAttribute, IExceptionFilter
        {
            // Fields
            private const string _defaultView = "Error";
            private string _master;
            private readonly object _typeId = new object();
            private string _view;
    
            // Methods
            public virtual void OnException(ExceptionContext filterContext)
            {
                if (filterContext == null)
                {
                    throw new ArgumentNullException("filterContext");
                }
                if (!filterContext.IsChildAction && (!filterContext.ExceptionHandled && filterContext.HttpContext.IsCustomErrorEnabled))
                {
                    Exception innerException = filterContext.Exception;
                    if ((new HttpException(null, innerException).GetHttpCode() == 500))
                    {
                        string controllerName = (string)filterContext.RouteData.Values["controller"];
                        string actionName = (string)filterContext.RouteData.Values["action"];
                        HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
                        ViewResult result = new ViewResult();
                        result.ViewName = this.View;
                        result.MasterName = this.Master;
                        result.ViewData = new ViewDataDictionary(model);
                        result.TempData = filterContext.Controller.TempData;
                        filterContext.Result = result;
                        filterContext.ExceptionHandled = true;
                        filterContext.HttpContext.Response.Clear();
                        filterContext.HttpContext.Response.StatusCode = 500;
                        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
                    }
                }
            }
    
            public string Master
            {
                get
                {
                    return (this._master ?? string.Empty);
                }
                set
                {
                    this._master = value;
                }
            }
    
            public override object TypeId
            {
                get
                {
                    return this._typeId;
                }
            }
    
            public string View
            {
                get
                {
                    if (string.IsNullOrEmpty(this._view))
                    {
                        return "Error";
                    }
                    return this._view;
                }
                set
                {
                    this._view = value;
                }
            }
        }
    

    Usage (untested cause I used it in context of controller that already implement all required interfaces)

    [HandleErrorAttribute]
    public class Foo : IExceptionFilter // (I am not sure about this one IActionFilter)
    {
    
        public void MethodA() 
        {
            // body
        }
    
        public void MethodB() 
        {
            // body
        }
    
        public void MethodC()
        {
            // body
        }
    
    }
    

    Or you can do something like this:

    public class ExecuteHelper
    {
        public static void Catch(Action action)
        {
            try
            {
                action();
            }
            catch (Exception ex)
            {
                // Do what you want
            }
        }
    }
    

    And use it in a Function body:

    public void Foo(string something)
    {
        ExecuteHelper.Catch(() =>
        {
            // Do something with something or without something
        });
    }
    

提交回复
热议问题