ASP.NET C#捕获类中的所有exception

我知道这不是这样做的方式,而且根本不干净。 我只是想知道是否可能。

如果我有一个带有一堆方法的类

public class Foo { methodA() {} methodB() {} methodC() {} } 

是否有可能捕获所有可能发生的exception而无需在每个方法中编写try / catch?

是的。 最简单的方法是这个类的属性,如下所示:

 [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; } } } 

用法(未经测试的原因我在已实现所有必需接口的控制器的上下文中使用它)

 [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 } } 

或者你可以这样做:

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

并在函数体中使用它:

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

你可以写一个更高阶的函数来处理exception,这会使它更清晰。

 private T FooExceptionHandler(Func function) { try { return function(); } catch { //handle it } } 

如果没有返回值,可以将Func替换为Action。 您可以在function之外以两种方式使用它:

 FooExceptionHandler(MethodA); 

或在每个function内:

 MethodA() { return FooExceptionHandler(()=> { //Function body goes here }); } 

不,没有。 try / catch块只能在方法中出现。 但是,您可以使用某种AOP框架来自动生成这些块。 postcrap是一个非常轻量级的AOP组件。

您可以在调用这些方法的函数中处理它…

默认情况下,在ASP.NET中,您可以覆盖OnError方法,然后执行Server.ClearError以处置exception。

我不确定它是否适用于您的情况(仅适用于PageGlobal.asax