ASP.NET MVC下自定义错误页和展示错误页的方式

在网站运行中,错误是不可避免的,错误页的产生也是不可缺少的。

这几天看了博友的很多文章,自己想总结下我从中学到的和实际中配置的。

首先,需要知道产生错误页的来源,一种是我们的.NET平台抛出的,一种是网站所依赖的宿主抛出的,一般来讲我们所依赖的宿主就是IIS了。

IIS中的错误页入口:

其中的错误码想必并不陌生

这里是在服务器上找不到所需资源时抛出的错误页,在这里可以设置需要展示的错误页面,只需将预定的错误页面加入服务器中,然后在指定状态码下配置路径即可。

这是请求在IIS中时,还未完全进入到asp.net mvc中,这里需要理解什么是未完全进入,IIS7+的版本中,不依赖于请求路径末尾的标识信息,利用mvc中的urlRoutingModule进行处理,在我们配置mvc的路由时,首先的第一条:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

便是隔离非mvc内部的使用文件,如果请求的只是服务器上的文件,那么路由便会在这里进行过滤,使之不匹配具体路由信息。

也就只是和mvc打了个招呼 然后就走了,没有进入mvc中搞事情。

第二种是,进入了asp.net mvc的管辖范围,然后在其中出错了,便是跳到我们在程序中配置的错误页了。

首先讲讲我从博友那里学到的、看到的几种方式。

第一种是在web.config中通过customError配置。

<customErrors mode="On" defaultRedirect="~/Error/ErrorPage">
   <error statusCode="404" redirect="~/Error/ErrorPage404" />
</customErrors>

但是这种方式不怎么令人接受,太过于简单,没有一点异常信息,并且有时候还不能起效果,我不太喜欢这种方式。

这种是用框架封装好的,利用的是将要说的第三种的强大方式实现的,当有异常发生又没得捕获时,最终利用的第三种方式自动实现。

第二种是利用HandlerErrorAttribute 特性,利用AOP的方式,当有异常出现时,便会进入具体实现了这个特性的,且被注册了的ExceptionAttribute职责中。

namespace SAssassin.Web.Core.Filter
{
  /// <summary>
  /// 异常处理之日志记载采用消息队列方式
  /// </summary>
  public class MyExceptionAttribute : HandleErrorAttribute
  {
    public static Queue<Exception> ExceptionQueue = new Queue<Exception>();
    public override void OnException(ExceptionContext filterContext)
    {
      ExceptionQueue.Enqueue(filterContext.Exception);
      filterContext.HttpContext.Response.Redirect("~/ErrorPage/CustomErrorPage");
      base.OnException(filterContext);
    }
  }
}

在这里,我可以得到异常信息,也可以解析具体的异常报错原因,比如404,500...  可以通过这种形势,将其转移到不同的自定义错误页面上,此处我增加了一个控制器

CustomErrorPageController,专门用来存放错误页面,原有的Shared下的Error.cshtml错误页面也仍然存在着。

我比较喜欢这种方式,一来可以看到异常信息,而来可以设计需要跳转的错误页面。

第三种方式也是最强大的、俗称"最后一道防线",从全局层面去捕捉异常的Application_Error

当网站初次启动时,会执行一个特殊的动作,Application_start 首先执行,也只初始化一次。这个也是Application 中的事件。

//
    // 摘要:
    //   ASP.NET 将 HTTP 标头发送到客户端之前发生。
    public event EventHandler PreSendRequestHeaders;
    //
    // 摘要:
    //   在选择该处理程序对请求作出响应时发生。
    public event EventHandler MapRequestHandler;
    //
    // 摘要:
    //   释放应用程序时发生。
    public event EventHandler Disposed;
    //
    // 摘要:
    //   作为执行的 HTTP 管道链中的第一个事件发生,当 ASP.NET 的请求做出响应。
    public event EventHandler BeginRequest;
    //
    // 摘要:
    //   当安全模块已建立的用户标识时出现。
    public event EventHandler AuthenticateRequest;
    //
    // 摘要:
    //   当安全模块已建立的用户标识时出现。
    public event EventHandler PostAuthenticateRequest;
    //
    // 摘要:
    //   安全模块已验证用户身份验证时发生。
    public event EventHandler AuthorizeRequest;
    //
    // 摘要:
    //   当前请求的用户已被授权时发生。
    public event EventHandler PostAuthorizeRequest;
    //
    // 摘要:
    //   当 ASP.NET 完成授权事件以便从缓存中,跳过的事件处理程序 (例如,一个页面或 XML Web 服务) 执行的请求提供服务的缓存模块时发生。
    public event EventHandler ResolveRequestCache;
    //
    // 摘要:
    //   ASP.NET 将绕过当前事件处理程序的执行,并允许缓存模块以处理从缓存请求时发生。
    public event EventHandler PostResolveRequestCache;
    //
    // 摘要:
    //   ASP.NET 将内容发送到客户端之前发生。
    public event EventHandler PreSendRequestContent;
    //
    // 摘要:
    //   当 ASP.NET 已映射到相应的事件处理程序的当前请求时出现。
    public event EventHandler PostMapRequestHandler;
    //
    // 摘要:
    //   当 ASP.NET 已完成处理的事件处理程序时发生 System.Web.HttpApplication.LogRequest 事件。
    public event EventHandler PostLogRequest;
    //
    // 摘要:
    //   已释放与请求相关联的托管的对象时发生。
    public event EventHandler RequestCompleted;
    //
    // 摘要:
    //   获取与当前的请求相关联的请求状态 (例如,会话状态) 时发生。
    public event EventHandler PostAcquireRequestState;
    //
    // 摘要:
    //   ASP.NET 开始执行事件处理程序 (例如,一个页面或 XML Web 服务) 之前发生。
    public event EventHandler PreRequestHandlerExecute;
    //
    // 摘要:
    //   当 ASP.NET 事件处理程序 (例如,一个页面或 XML Web 服务) 完成执行时发生。
    public event EventHandler PostRequestHandlerExecute;
    //
    // 摘要:
    //   ASP.NET 完成执行所有请求事件处理程序后发生。 此事件会导致状态模块保存当前的状态数据。
    public event EventHandler ReleaseRequestState;
    //
    // 摘要:
    //   当 ASP.NET 已完成执行所有请求事件处理程序和存储数据的请求状态时发生。
    public event EventHandler PostReleaseRequestState;
    //
    // 摘要:
    //   当 ASP.NET 完成执行事件处理程序,以便让缓存模块存储将用于为从缓存中的后续请求提供服务的响应时发生。
    public event EventHandler UpdateRequestCache;
    //
    // 摘要:
    //   当 ASP.NET 完成更新的缓存模块和存储用于为从缓存中的后续请求提供服务的响应时发生。
    public event EventHandler PostUpdateRequestCache;
    //
    // 摘要:
    //   ASP.NET 执行当前请求的任何日志记录之前发生。
    public event EventHandler LogRequest;
    //
    // 摘要:
    //   当 ASP.NET 获取与当前的请求相关联的当前状态 (例如,会话状态)。
    public event EventHandler AcquireRequestState;
    //
    // 摘要:
    //   作为执行的 HTTP 管道链中的最后一个事件发生,当 ASP.NET 的请求做出响应。
    public event EventHandler EndRequest;
    //
    // 摘要:
    //   当引发未处理的异常时发生。
    public event EventHandler Error;

看到最后一个事件,当引发未处理的异常时发生,便是最后一道防线登场了。如果没有用aop的方式捕捉异常,那么就是Application _Error登场了。

在Global.asax中我们可以写上这个方法

    /// <summary>
    /// 可以完成全局异常处理
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Application_Error(object sender, EventArgs e)
    {
      // 在出现未处理的错误时运行的代码
      var error = Server.GetLastError();
      var code = (error is HttpException) ? (error as HttpException).GetHttpCode() : 500;

      //如果不是HttpException记录错误信息
      if (code != 404)
      {
        //此处邮件或日志记录错误信息
      }

      Response.Write("出错");
      Server.ClearError();

      string path = Request.Path;
      Context.RewritePath(string.Format("~/Errors/Http{0}", code), false);
      IHttpHandler httpHandler = new MvcHttpHandler();
      httpHandler.ProcessRequest(Context);
      Context.RewritePath(path, false);
    }

这个方法中,我们也可以得到异常信息,记录日志或是邮件通知,

同样可以根据错误码进行相应的跳转错误页面。

也可以在当前错误页面中添加额外的信息。

很是强大。

如果没有写这个方法,则利用框架封装的默认方法。当在web.config中配置了customError节点时,便是这个方法来帮忙处理。

或许还有更多更好的方式。望指导指导,我想学习学习。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • ASP.NET MVC自定义错误页面真的简单吗?

    如果你在设置asp.net mvc自定义错误页面时遇到问题,这并不止你一个人.惊讶之余你的做法是正确的,没有起到作用的原因是其一部分错误是由asp.net管道处理的,另一部分是由iis直接处理. 通常情况 (我期望是这种情况,在一些其他框架/服务器上) 我们只需要在一个地方配置自定义错误页就可以了,无论怎么哪儿引发的错误.就像这样︰ <customErrors mode="On"> <error code="404" path="404.

  • ASP.NET MVC下自定义错误页和展示错误页的方式

    在网站运行中,错误是不可避免的,错误页的产生也是不可缺少的. 这几天看了博友的很多文章,自己想总结下我从中学到的和实际中配置的. 首先,需要知道产生错误页的来源,一种是我们的.NET平台抛出的,一种是网站所依赖的宿主抛出的,一般来讲我们所依赖的宿主就是IIS了. IIS中的错误页入口: 其中的错误码想必并不陌生 这里是在服务器上找不到所需资源时抛出的错误页,在这里可以设置需要展示的错误页面,只需将预定的错误页面加入服务器中,然后在指定状态码下配置路径即可. 这是请求在IIS中时,还未完全进入到a

  • ASP.NET MVC下拉框中显示枚举项

    本篇将通过3种方式,把枚举项上的自定义属性填充到下拉框:1.通过控制器返回List<SelectListItem>类型给前台视图2.通过为枚举类型属性打上UIHint属性让模版显示枚举项3.通过自定义元数据提供器DataAnnotationsModelMetadataProvider让模版显示枚举项 我们经常会把类型为Int16的属性通过枚举来获得.比如: public class SomeClass { public int16 Status{get;set;} } 对应的枚举: publi

  • ASP.NET MVC下的四种验证编程方式[续篇]

    在<ASP.NET MVC的四种验证编程方式>一文中我们介绍了ASP.NET MVC支持的四种服务端验证的编程方式("手工验证"."标注ValidationAttribute特性"."让数据类型实现IValidatableObject或者IDataErrorInfo"),那么在ASP.NET MVC框架内部是如何提供针对这四种不同编程方式的支持的呢?接下来我们就来聊聊这背后的故事. 一.ModelValidator与ModelVali

  • ASP.NET MVC下Ajax.BeginForm方式无刷新提交表单实例

    有时候,不得不考虑到以下场景问题: 数据库表字段会频繁更改扩展,而流行的重业务的js框架过于依赖json数据接口,导致的问题是,数据库表更改 -> 数据接口更改 -> 前段框架逻辑更改... 一不小心就陷入坑坑洼洼. 这样的话,原来纯ASP.NET MVC绑定的方式,还是可以一用的,因为该方式不用再为那么多js代码烦恼. 不好意思,前面自说自话啊,直接上干货代码了---- Ajax.BeginForm @{ Layout = null; var ajaxOptions = new AjaxOp

  • ASP.NET MVC下基于异常处理的完整解决方案总结

    EntLib的异常处理应用块(Exception Handling Application Block)是一个不错的异常处理框架,它使我们可以采用配置的方式来定义异常处理策略.而ASP.NET MVC是一个极具可扩展开发框架,在这篇文章中我将通过它的扩展实现与EntLib的集成,并提供一个完整的解决异常处理解决方案. 一.基本异常处理策略 我们首先来讨论我们的解决方案具体采用的异常处理策略: 对于执行Controller的某个Action方法抛出的异常,我们会按照指定配置策略进行处理.我们可以采

  • asp.net MVC利用自定义ModelBinder过滤关键字的方法(附demo源码下载)

    本文实例讲述了MVC利用自定义ModelBinder过滤关键字的方法.分享给大家供大家参考,具体如下: 前面一篇主要讲解了如何利用ActionFilter过滤关键字,这篇主要讲解如何利用自己打造的ModelBinder来过滤关键字. 首先,我们还是利用上一篇<asp.net MVC利用ActionFilterAttribute过滤关键字的方法>中的实体类,但是我们需要加上DataType特性,以便于我们构造的ModelBinder通过DataTypeName识别出来: using System

  • 详解ASP.NET MVC下的异步Action的定义和执行原理

    Visual Studio提供的Controller创建向导默认为我们创建一个继承自抽象类Controller的Controller类型,这样的Controller只能定义同步Action方法.如果我们需要定义异步Action方法,必须继承抽象类AsyncController.这篇问你讲述两种不同的异步Action的定义方法和底层执行原理. 一.基于线程池的请求处理 ASP.NET通过线程池的机制处理并发的HTTP请求.一个Web应用内部维护着一个线程池,当探测到抵达的针对本应用的请求时,会从池

  • Asp.net MVC下使用Bundle合并、压缩js与css文件详解

    前言 介绍本文的正式内容之前先引用<淘宝技术这十年>中一段话,对Web前端稍微有点常识的人都应该知道,浏览器下一步会加载页面中用到的CSS.JS(JavaScript).图片等样式.脚本和资源文件.但是可能相对较少的人才会知道,你的浏览器在同一个域名下并发加载的资源数量是有限的,例如IE 6和IE 7是两个,IE 8是6个,chrome各版本不大一样,一般是4-6个.Bundle是ASP.NET 4.5中的一个新特性,可 用来将js和css进行压缩(多个文件可以打包成一个文件,也可以说是合并多

  • ASP.NET MVC下Bundle的使用方法

    ASP.NET MVC中Bundle是用于打包捆绑资源的(一般是css和js),它是在全局文件Global.asax.cs中注册Bundle,而注册的具体实现默认是在App_Start文件夹的BundleConfig.cs中 public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); Filt

  • asp.net MVC下使用rest的方法

    前言 最近做了下个MVC的项目,需要用到rest接口,与java写的应用程序通信,包括数据的接收和发送,那么我将用实用的角度来全面的讲解一下它的使用方法 一.创建rest服务 首先创建一个Asp.Net Web应用程序(我这里用的是Visual Studio 2013,它已经内置了Web API2). 在出来的模板中选择Empty(空项目),并勾选WebAPI.点击确定后,就创建了一个空的WebAPI服务. 此时只有一个空项目,还没有任何功能,在进行下一步之前,首先我们来看一下REST的基本操作

随机推荐