1. 程式人生 > >MVC4 自定義錯誤頁面(三)

MVC4 自定義錯誤頁面(三)

gif static quest glob logger tool iis def .cn

一、概述

MVC4框架自帶了定義錯誤頁,該頁面位於Shared/Error,該頁面能夠顯示系統未能捕獲的異常,如何才能使用該頁面;

二、使用步驟:

1、配置WebConfig文件,在System.Web節點下加上

<customErrors mode="On"  defaultRedirect="~/Shared/Error" />

翻閱一些大神寫的博客,在他們的博客中指出defaultRedirect是指向錯誤頁面的URL,可是經過本人測試的時候,發現在MVC4中這種說法並不準,在MVC中,有一套默認的機制(這部分代碼被微軟封裝,無法閱讀),該機制能夠把錯誤信息通過HandleError屬性指向Shared/Error頁面,也就是說配置System.Web節點,可以省略defaultRedirect

customErrors mode="On"/>   

2、Global文件,添加HandleEffor屬性

 public static void RegisterGlobalFilters(GlobalFilterCollection filters)
 {
       filters.Add(new HandleErrorAttribute(),1);            
 }

在Global定義之後,也就是全局定義,其他Action和Control都不需要定義,默認使用HandleError控制屬性;

這樣就可以使用MVC4中系統默認的Error頁面;

三、自定義錯誤頁面

  有些時候,我們想使用自定義的錯誤頁面,該怎麽處理那,翻頁其他大牛寫的博客,看到有這種方式,自定義屬性Class繼承FileterAttribute,重寫OnException方法,代碼如下

技術分享
public class BaseHandleErrorAttribute : FilterAttribute, IExceptionFilter
    {
        public void OnException(ExceptionContext filterContext)
        {
            if (filterContext.ExceptionHandled == true)
            {
                HttpException httpExce = filterContext.Exception as HttpException;
                if (httpExce != null && httpExce.GetHttpCode() != 500)//為什麽要特別強調500 因為MVC處理HttpException的時候,如果為500 則會自動將其ExceptionHandled設置為true,那麽我們就無法捕獲異常
                {
                    return;
                }
            }
            Exception exception = filterContext.Exception;            
            if (exception != null)
            {
                HttpException httpException = exception as HttpException;
                if (httpException != null)
                {
                    //網絡錯誤
                    filterContext.Controller.ViewBag.UrlRefer = filterContext.HttpContext.Request.UrlReferrer;
                    int DataEroorCode = httpException.GetHttpCode();
                    if (DataEroorCode == 404)
                    {
                        filterContext.HttpContext.Response.Redirect("~/SysError/404");
                    }
                    else if (DataEroorCode == 500)
                    {
                        filterContext.HttpContext.Response.Redirect("~/SysError/500");
                    }
                    else
                        filterContext.HttpContext.Response.Redirect("~/SysError/" + DataEroorCode);

                    //寫入日誌 記錄
                    filterContext.ExceptionHandled = true;//設置異常已經處理
                }
                else
                {
                    //編程或者系統錯誤,不處理,留給HandError處理
                }
            }                     
        }
    }
技術分享

將該屬性註冊到全局Global中,定義鋪貨異常等級

技術分享
      public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new BaseHandleErrorAttribute(),0);

            filters.Add(new HandleErrorAttribute(),1);
            
        }
技術分享

當然我們也可以不使用MVC框架自帶的Error頁面,定義一個Error404,如何使用這個頁面那 ,起始也挺簡單的,代碼如下

技術分享
      public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new BaseHandleErrorAttribute(),0);

            filters.Add(new HandleErrorAttribute(View="Error404"),1);
            
        }
技術分享

四、遇到問題總結

1、遇到重定向,URL指向aspxerrorpath,如:

http://local:8090/error/error.htm?aspxerrorpath=/cmt/p/3789549.html

出現這個問題的主要原因:

1>、Global沒有添加

filters.Add(new HandleErrorAttribute(View="Error404"))

2>、Shared目錄沒有Error頁面;

3>、如果存在Error頁面,但是頁面是用了布局Layout,組成的Error頁面存在錯誤,比如ModeView數據不對等,需要詳查;

2、自定義Error的其他方式

翻頁其他大牛寫的文章時候,返現也可以使用Gloal中的Application_Error事件方法處理,比如博主@dudu寫的異常處理方式;

代碼粘貼如下:

技術分享
protected void Application_Error(Object sender, EventArgs e)
{
    var lastError = Server.GetLastError();
    if (lastError != null)
    {
        var httpError = lastError as HttpException;
        if (httpError != null)
        {
            //ASP.NET的400與404錯誤不記錄日誌,並都以自定義404頁面響應
            var httpCode = httpError.GetHttpCode();
            if (httpCode == 400 || httpCode == 404)
            {
                Response.StatusCode = 404;//在IIS中配置自定義404頁面
                Server.ClearError();
                return;
            }
            Logger.Default.Error("Application_Error_" + httpCode, httpError);
        }

        //對於路徑錯誤不記錄日誌,並都以自定義404頁面響應
        if (lastError.TargetSite.ReflectedType == typeof(System.IO.Path))
        {
            Response.StatusCode = 404;
            Server.ClearError();
            return;
        }

        Logger.Default.Error("Application_Error", lastError);
        Response.StatusCode = 500;
        Server.ClearError();
    }
}
技術分享

實現樣式多樣,只要實現功能就是最好;

MVC4 自定義錯誤頁面(三)