MVC 框架 - 异常处理

在 ASP.NET 中,错误处理是使用标准 try catch 方法或使用应用程序事件完成的。ASP.NET MVC 内置了对异常处理的支持,使用称为异常过滤器的功能。我们将在这里学习两种方法:一种是覆盖 onException 方法,另一种是定义 HandleError 过滤器。

覆盖 OnException 方法

当我们想要在控制器级别处理 Action 方法中的所有异常时,使用此方法。

要了解这种方法,请创建一个 MVC 应用程序(按照前面章节中介绍的步骤进行操作)。现在添加一个新的 Controller 类,并添加以下代码,该代码将覆盖 onException 方法并在我们的 Action 方法中明确抛出错误 −

MVC Exception Handling

现在让我们创建一个名为 Error 的通用视图,当应用程序中发生任何异常时,它将显示给用户。在 Views 文件夹中,创建一个名为 Shared 的新文件夹,并添加一个名为 Error 的新视图。

MVC Error Handling

将以下代码复制到新创建的 Error.cshtml 中 −

MVC Exception Common View

如果您现在尝试运行该应用程序,它将给出以下结果。当此控制器中的任何操作方法发生任何异常时,上述代码都会呈现错误视图。

MVC 常见异常处理

这种方法的优点是同一控制器中的多个操作可以共享此错误处理逻辑。但是,缺点是我们不能在多个控制器中使用相同的错误处理逻辑。

HandleError 属性

HandleError 属性是我们在过滤器和操作过滤器一章中研究的操作过滤器之一。HandleErrorAttribute 是 IExceptionFilter 的默认实现。此过滤器处理控制器操作、过滤器和视图引发的所有异常。

要使用此功能,首先打开 web.config 中的 customErrors 部分。打开 web.config,将以下代码放入 system.web 中,并将其值设置为 On。

<customErrors mode = "On"/>

我们已经在 Views 下的 Shared 文件夹中创建了 Error View。这次将此 View 文件的代码更改为以下内容,使用 HandleErrorInfo 模型(位于 System.Web.MVC 下)对其进行强类型化。

@model System.Web.Mvc.HandleErrorInfo 

@{ 
Layout = null; 
} 
  
<!DOCTYPE html> 
<html> 
   <head> 
      <meta name = "viewport" content = "width = device-width" /> 
      <title>Error</title> 
   </head> 
   
   <body> 
      <h2> 
         Sorry, an error occurred while processing your request.  
      </h2> 
      <h2>Exception details</h2> 
      
      <p> 
         Controller: @Model.ControllerName <br> 
         Action: @Model.ActionName 
         Exception: @Model.Exception 
      </p> 
   
   </body> 
</html> 

现在将以下代码放入您的控制器文件中,该代码在控制器文件中指定 [HandleError] 属性。

using System; 
using System.Data.Common; 
using System.Web.Mvc;  

namespace ExceptionHandlingMVC.Controllers { 
   [HandleError] 
   public class ExceptionHandlingController : Controller { 
      
      public ActionResult TestMethod() { 
         throw new Exception("Test Exception"); 
         return View(); 
      } 
   } 
}

如果您现在尝试运行该应用程序,您将收到类似于以下屏幕截图所示的错误。

MVC Exception

如您所见,这次错误包含有关控制器和操作相关详细信息的更多信息。通过这种方式,HandleError 可以在任何级别和跨控制器使用来处理此类错误。