整理ASP.NET MVC 5各种错误请求[401,403,404,500]的拦截及自定义页面处理实例

ASP.NET MVC 2015-10-02 1765浏览 收藏本文

ASP.NET MVC 5的开发中,服务器的各种错误[如:401(登录授权验证),403(禁止访问),404(访问页面不存在),500(服务器内部错误)等]处理是必需考虑并解决的一个问题,如果不处理这些错误或者使用默认的错误页面,那么用于用户体验来说就不是很友好了。严重的甚至可以暴露程序以及服务器的各种信息,给黑客以可乘之机。 网上关于ASP.NET MVC 5的服务器错误处理拦截问题没有太全的总结和整理。今天用一个简单实例来总结整理一下这方面的处理技巧。 首先是404页面的处理,本示例利用Global.asax文件的Application_Error()方法来拦截,使用Server.GetLastError()方法获取到服务器的最后一次错误作为HttpException,再根据httpException的GetHttpCode()方法获取到的http状态码来处理404的页面不存在的问题,Global.asax代码如下:

protected void Application_Error(object sender, EventArgs e)
    {
      Exception exception = Server.GetLastError();
      HttpException httpException = exception as HttpException;

      RouteData routeData = new RouteData();
      routeData.Values.Add("controller", "Error");

      switch (httpException.GetHttpCode())
      {
        case 404:
          routeData.Values.Add("action", "HttpError404");
          break;
      }

      Response.Clear();
      Server.ClearError();
      Response.TrySkipIisCustomErrors = true;
      IController errorController = new ErrorController();
      errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));

      //Response.RedirectToRoute(new { controller = "Error", action = "HttpError404" });
    }
以上的404错误处理是直接将事先制作好的HttpError404.cshtml视图信息显示在请求的页面,如: asp-net-mvc-5-404-custom-handle-01 其次是401(未授权)页面的拦截处理,本示例是创建了一个名为AuthorizeCheckAttribute属性类,此类继承至AuthorizeAttribute类,在AuthorizeCheckAttribute类中,重写了HandleUnauthorizedRequest方法,我们中此方法中来处理所有需要授权但未授权访问的请求,然后再在需要授权访问的控制器或者Action上使用AuthorizeCheck属性,AuthorizeCheckAttribute属性类的代码如下:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
      base.HandleUnauthorizedRequest(filterContext);
      if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
      {
        try
        {
          filterContext.Controller.TempData.Add("Alert", new Alert { Type = AlertType.Error, Message = "请登录后访问" });
        }
        catch { }
        filterContext.Result = new ViewResult
        {
          TempData = filterContext.Controller.TempData,
          ViewName = "~/Views/Error/HttpError401.cshtml"
        };
        //new RedirectResult("~/error/httperror401");
      }
    }
需要授权访问的Action如下:
    [AuthorizeCheck]
    public ActionResult UnAuthorize()
    {
      return View();
    }
这样,如果在未登录授权的情况下访问UnAuthorize这个Action,那么就会被拦截到。我们可以在拦截器里任意处理错误信息了,比如把错误记录到日志等。 最后,我们来处理的服务器的500内部错误。首先创建一个名为CustomHandleErrorAttribute的自定义错误处理属性类,此类继承至HandleErrorAttribute类,在CustomHandleErrorAttribute类中重写OnException方法,代码如下:
public override void OnException(ExceptionContext filterContext)
    {
      base.OnException(filterContext);
      Exception exception = filterContext.Exception;
      try
      {
        //TODO:写错误日志
        filterContext.Controller.TempData.Add("Alert", new Alert { Type = AlertType.Error, Message = exception.ToString() });
      }
      catch { }
      filterContext.ExceptionHandled = true;
      filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;

      //filterContext.Result = new RedirectResult("~/error/httperror500");
      filterContext.Result = new ViewResult
      {
        TempData=filterContext.Controller.TempData,
        ViewName = "~/Views/Error/HttpError500.cshtml"
      };
      //var Result = this.View("Error", new HandleErrorInfo(exception,
      //filterContext.RouteData.Values["controller"].ToString(),
      //filterContext.RouteData.Values["action"].ToString()));

      //filterContext.Result = Result;
    }
以上代码中,我们使用了filterContext.Result属性来设置拦截到内部错误后的返回视图名字和返回的信息。当然,在OnException这个重写方法中,我们还可以处理日志等操作,根据自已需要来实现就行。写好这个类后,我们再修改FilterConfig类的RegisterGlobalFilters的方法,如下:
public class FilterConfig
  {
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
      filters.Add(new CustomHandleErrorAttribute());
    }
  }
当然,我们事先已经在Global.asax文件中注册了全局拦截配置了,Application_Start代码如下:
 protected void Application_Start()
    {
      AreaRegistration.RegisterAllAreas();
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
      RouteConfig.RegisterRoutes(RouteTable.Routes);
      BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
好了,以上就是关于ASP.NET MVC 5中处理各种服务器错误的自定义页面的操作,希望对你有所帮助。 如果你有更好的实现方法,也欢迎留言交流。 最后,我把本实例的代码提供如下,点击这里下载

转载请注明:图享网 » 整理ASP.NET MVC 5各种错误请求[401,403,404,500]的拦截及自定义页面处理实例