【MVC】MVC 4 自定义错误页面

我们知道,当年我们新建一个MVC 4项目, VS 自带的模板就会:

1)自动在Views/Shared 文件夹下面自动添加一个Error.cshtml 文件,这个文件就是我们自定义错误页面经常使用的

2)会在App_Start/FilterConfig.cs 中添加一个关于错误处理的Global Filter.

  filters.Add(newHandleErrorAttribute());

 

要开启自定义错误页面,我们自己需要做的就是:

1)修改 Error.cshtml , 让其按我们的方式/样式展现错误信息

2)修改 Web.config,开启 custom error

<customErrorsmode="On"/>

 

那,mvc 是怎么帮我们处理的的呢, 他们如何转向Error.cshtml 视图的,又是怎么给Model赋值的?

一开时,我以为 mvc  有一个内置的ErrorController --- 因为这符合 从Controller - > view的一般思维--- 来控制的, 事实上不是的!这一切都使由 HandleErrorAttribute 来控制的。

 

我们来看一看HandleErrorAttribute 的定义: 

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class HandleErrorAttribute : FilterAttribute, IExceptionFilter

可以看到, 它既是一个 Attribute 也是一个 Filter。也就是说我们既可以针对具体的Controller或者Action来设置,

    [HandleError]
    public class TaskStatusController : GridControllerBase
    {
        [HandleError]
        public ActionResult Index()
        {

也可以在注册在 GlobalFilterCollection里(默认生成这样的), 作为一个全局的

    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }
    }

当然,这些还不足以说明 custom error 是怎么工作的, 我们通过反射看一下HandleErrorAttribute这个类, 就会很明晰了:

    ....
    private const string DefaultView = "Error";
    ...
    /// <summary>
    /// Called when an exception occurs.
    /// </summary>
    /// <param name="filterContext">The action-filter context.</param><exception cref="T:System.ArgumentNullException">The <paramref name="filterContext"/> parameter is null.</exception>
    public virtual void OnException(ExceptionContext filterContext)
    {
      if (filterContext == null)
        throw new ArgumentNullException("filterContext");
      if (filterContext.IsChildAction || filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
        return;
      Exception exception = filterContext.Exception;
      if (new HttpException((string) null, exception).GetHttpCode() != 500 || !this.ExceptionType.IsInstanceOfType((object) exception))
        return;
      string controllerName = (string) filterContext.RouteData.Values["controller"];
      string actionName = (string) filterContext.RouteData.Values["action"];
      HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
      ExceptionContext exceptionContext = filterContext;
      ViewResult viewResult1 = new ViewResult();
      viewResult1.ViewName = this.View;
      viewResult1.MasterName = this.Master;
      viewResult1.ViewData = (ViewDataDictionary) new ViewDataDictionary<HandleErrorInfo>(model);
      viewResult1.TempData = filterContext.Controller.TempData;
      ViewResult viewResult2 = viewResult1;
      exceptionContext.Result = (ActionResult) viewResult2;
      filterContext.ExceptionHandled = true;
      filterContext.HttpContext.Response.Clear();
      filterContext.HttpContext.Response.StatusCode = 500;
      filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
    }

注意 02 行, 默认的错误处理页面就是Error 这个 view

同时注意21,22, 这里代码我没有贴全,反正就是直接呈现Error 这个视图了, 没有经过任何 Controller!




 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值