ASP.NET MVC错误处理的对应解决方法

2019-05-25 13:51:30王冬梅

3.2捕获未匹配的路由

在路由注册列表最底端注册路由。

public class RouteConfig
  {
    public static void RegisterRoutes(RouteCollection routes)
    {
      //其他配置
      routes.MapRoute(
        name: "MatchAll",
        url: "{*anyurl}",
        defaults: new { controller = "Error",action ="Missing" }
        );
     }
   }

定义Error控制器及Missing操作

public class ErrorController : Controller
  {
    // GET: Error
    public ActionResult Missing()
    {
      HttpContext.Response.StatusCode = 404;
      //禁用IIS7默认的错误页,这样才能展示我们指定都的视图
      HttpContext.Response.TrySkipIisCustomErrors = true;

      //也可以在此处记录日志信息

      //要展示的信息
      var model = ......
      return View(model);
    }
   }

需要注意的是,这种方式不一定能处理所有未匹配的情形。

例如:http://localhost/mvcpointapp/home/index1,这个url请求说我home是存在,但是index1操作不存在,上面配置MatchAll路由无法匹配这个url。

可以匹配的情形如:http://localhost/mvcpointapp/v1/home/index/1,这个url能被上面配置的MatchAll路由匹配,所以可以显示Missing视图。

4实践

4.1使用HandleErrorAttribute注意要对<system.web>的<customErrors>节进行设置 。

例如:

控制器为

public class HomeController : Controller
  {
    [HandleError(ExceptionType = typeof(KeyNotFoundException), View = "Error")]
    public ActionResult Index()
    {
      throw new KeyNotFoundException();
      return View();
    }

    //其他控制操作

   }

<system.web>的<customErrors>节

<customErrors mode="On" defaultRedirect="Error/Error2"></customErrors>

Error.cshtml文件位于Views文件夹下的子文件夹Shared文件夹下

浏览器中输入:http://localhost/mvcpointapp/

结果可以正常显示Error.cshtml页面,同时注意到虽然在customErrors 配置节中指定了defaultRedirect,但还是跳转到Error.cshtml页面。

将<customErrors>的mode设置为Off,则显示经典错误页。

4.2 Application_Error

代码如3.1节所示,控制器如4.1所示,<system.web>的<customErrors>节为<customErrors mode="On" defaultRedirect="Error/Error2"></customErrors>

输入:http://localhost/mvcpointapp/home/index,断点调试,发现错误被HandleError拦截,Global.asax的Application_Error方法没有执行。而当输入:http://localhost/mvcpointapp/home/indexr,Application_Error执行了。

关闭<customErrors>配置节,而不注掉控制器上的HandleErrorAttribute特性,输入:http://localhost/mvcpointapp/home/index,发现Application_Error执行了。

通过上述实践,充分证明HandleErrorAttribute会拦截控制器内抛出的异常,而无法拦截无法找到资源这种异常。