如何在ASP.NET MVC中有效处理异常?

## ASP.NET MVC中异常处理

如何在ASP.NET MVC中有效处理异常?

在ASP.NET MVC应用程序中,异常处理是一个关键的方面,用于确保应用程序的稳定性和可靠性,异常处理不仅能够捕获并处理运行时错误,还能防止敏感信息泄露,并提供友好的用户界面,本文将详细介绍ASP.NET MVC中的几种主要异常处理方法,包括全局异常处理、局部异常处理以及自定义异常处理。

### 一、全局异常处理

#### 1. 使用 `` 节点`` 是ASP.NET中的一个配置节,用于定义自定义错误信息,它有两个主要属性:

**mode**: 可选值有 "On", "Off" 和 "RemoteOnly"。"On"表示本地和远程用户都会看到自定义错误信息;"Off"表示显示详细的错误信息;"RemoteOnly"表示本地用户看到详细错误信息,远程用户看到自定义错误信息。

**defaultRedirect**: 可选属性,指定发生错误时重定向到的默认URL。

示例如下:

```xml

```

在这个配置中,如果用户访问的页面不存在就会跳转到404.htm页面,如果用户没有权限访问请求的页面则会跳转到403.htm页面。

#### 2. 使用过滤器 `HandleErrorAttribute`

`HandleErrorAttribute` 是一个过滤器,用于处理Action级别的异常,当程序中出现异常时,会封装这些异常信息,然后路由自动转到该Controller对应的 `Error.cshtml` 中,如果此路径下没有改文件,则会到shared目录中寻找此文件。

示例代码:

```csharp

[HandleError]

public class HomeController : Controller

public ActionResult Index()

{

throw new Exception("测试异常");

return View();

}

```

需要注意的是,`HandleErrorAttribute` 是在 `` 基础之上的,如果想使用 `HandleErrorAttribute`,`` 的Mode必须要设置为 "On" 或 "RemoteOnly"。

#### 3. 自定义显示路径

除了简单的错误重定向,还可以通过继承扩展 `HandleErrorAttribute` 来实现新的Filter,然后在Global.asax中对所有的Action进行注册。

```csharp

public class MyHandleErrorAttribute : FilterAttribute, IExceptionFilter

public void OnException(ExceptionContext filterContext)

{

if (filterContext.ExceptionHandled || filterContext.HttpContext.IsCustomErrorEnabled)

return;

var ex = filterContext.Exception;

filterContext.ExceptionHandled = true;

filterContext.Result = new ViewResult { ViewName = "Error" };

filterContext.HttpContext.Response.Clear();

filterContext.HttpContext.Response.StatusCode = 500;

filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;

}

```

然后在Global.asax中注册:

```csharp

protected void Application_Start()

filters.Add(new MyHandleErrorAttribute());

如何在ASP.NET MVC中有效处理异常?

```

### 二、局部异常处理

#### 1. 使用 `OnException` 方法

可以在Controller类中重写 `OnException` 方法来处理控制器范围内的异常。

```csharp

public class BaseController : Controller

protected override void OnException(ExceptionContext filterContext)

{

//记录日志

Log.Error(filterContext.Exception);

//设置错误页面

filterContext.Result = new RedirectResult("/ErrorHandler/Index");

}

```

然后让其他控制器继承这个BaseController:

```csharp

public class HomeController : BaseController

public ActionResult Index()

{

throw new Exception("测试异常");

return View();

}

```

#### 2. 使用 `[HandleError]` 特性

可以在特定的Action上使用 `[HandleError]` 特性来处理该Action的异常。

```csharp

[HandleError]

public ActionResult About()

throw new Exception("测试异常");

return View();

```

这种方法比较灵活,可以为不同的Action定义不同的错误页,不过需要注意的是,这种方式不能记录日志,因为没有Action可以调用记录日志的方法。

### 三、自定义异常处理

为了更好地控制异常处理流程,可以通过实现自定义的异常过滤器来实现更复杂的逻辑。

```csharp

public class CustomExceptionFilter : FilterAttribute, IExceptionFilter

public void OnException(ExceptionContext filterContext)

{

if (filterContext.ExceptionHandled || filterContext.HttpContext.IsCustomErrorEnabled)

return;

如何在ASP.NET MVC中有效处理异常?

var ex = filterContext.Exception;

filterContext.ExceptionHandled = true;

filterContext.Result = new RedirectResult("/CustomError");

filterContext.HttpContext.Response.Clear();

filterContext.HttpContext.Response.StatusCode = 500;

filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;

}}

```

然后在Global.asax中注册:

```csharp

protected void Application_Start()

filters.Add(new CustomExceptionFilter());

```

### 四、归纳与建议

**选择合适的异常处理方式**:根据具体需求选择合适的异常处理方式,对于全局性的异常处理,可以使用 `` 节点或全局异常过滤器;对于局部性的异常处理,可以使用 `[HandleError]` 特性或重写 `OnException` 方法。

**记录日志**:无论使用哪种异常处理方式,都应记录详细的异常信息以便后续分析,可以通过日志框架(如NLog、log4net等)来实现日志记录。

**友好的错误页面**:为用户提供友好的错误页面,避免暴露敏感信息,可以使用强类型视图模型(如 `HandleErrorInfo`)来显示详细的异常信息。

**安全性考虑**:确保在开发调试阶段关闭自定义错误页面,以便于查找错误;在生产环境中启用自定义错误页面,以防止敏感信息泄露。

### 五、单元表格对比不同异常处理方式的特点

| 异常处理方式 | 适用场景 | 优点 | 缺点 |

|----------------|------------|---------|---------|

| | 全局异常处理 | 简单易用 | 无法记录日志 |

| HandleErrorAttribute | Action级别异常处理 | 灵活可定制 | 需要额外配置 |

| OnException | 控制器范围内异常处理 | 集中管理 | 无法单独处理每个Action的异常 |

| [HandleError] | 特定Action异常处理 | 灵活可定制 | 无法记录日志 |

| 自定义异常过滤器 | 复杂逻辑处理 | 高度可定制 | 实现复杂度高 |

### 六、相关问题与解答

**问题1**: 如何在ASP.NET MVC中记录异常日志?

**解答**: 可以使用日志框架(如NLog、log4net等)在异常处理过程中记录日志,在 `OnException` 方法或自定义异常过滤器中使用日志框架记录异常信息。

**问题2**: 如何在ASP.NET MVC中提供友好的错误页面?

**解答**: 可以使用强类型视图模型(如 `HandleErrorInfo`)在错误页面中显示详细的异常信息,首先创建一个 `HandleErrorInfo` 类来封装异常信息,然后在错误视图中使用该模型来显示异常信息。

```csharp

@model Artech.Mvc.ExceptionHandling.Models.HandleErrorInfo

@{

ViewBag.Title = "错误";

项目名称

@Model.Exception.Message

@Model.Exception.StackTrace

```

各位小伙伴们,我刚刚为大家分享了有关“ASP.NET MVC中异常处理”的知识,希望对你们有所帮助。如果您还有其他相关问题需要解决,欢迎随时提出哦!