ASP.NET MVC中錯誤處理方式

來源:互聯網
上載者:User

aspnet mvc的錯誤處理方式主要有以下兩種

方式一:通過對controller或者action標記HandleError屬性,然後指定一個錯誤頁即可。這種方式最簡單,不需要額外增加action ,僅僅需要增加錯誤頁,但是不能記錄日誌(因為沒有action,其實在aspx中也可調用記錄日誌的方法)。這個錯誤頁還可以定義為強型別,類型為HandleErrorInfo,具體的Model又架構傳遞,可擷取具體的異常資訊。

 

HandlError

/// <summary>
        /// 標記了HandleError,並指明錯誤處理頁為AboutError.aspx
        /// </summary>
        /// <returns></returns>
        [HandleError(View = "AboutError")]
        public ActionResult About()
        {
            return View();
        }

AboutError.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<HandleErrorInfo>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    AboutError
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    通過強型別擷取異常資訊
    <%= Model.Exception.Message %>
</asp:Content>

這種方式比較靈活,比如需要對某個action定義個錯誤頁,就可採用這種方式。不過會有個小問題,後面會提到。

 

方式二:重寫controller類的onException方式,這種方式最直接了,通常用於一個項目的BaseController中,那麼以後的controller都繼承這個類即可,可以在cs代碼中記錄錯誤記錄檔,但是要定義錯誤頁的action和具體的錯誤頁面。方法中需要設定ExceptionHandled=true,否則錯誤會被拋到外層,這時候只能通過傳統的aspnet錯誤方式處理了,通常是招CustomerError中配置的錯誤頁,如果沒有配置,那就出現一個大黃頁了。ExceptionHandled=true這個操作會是邏輯有微妙的變化,後續提到。

重寫OnException

 protected override void OnException(ExceptionContext filterContext)
        {
            // 標記異常已處理
            filterContext.ExceptionHandled = true;
            // 跳轉到錯誤頁
            filterContext.Result = new RedirectResult(Url.Action("Error", "Shared"));
        }

 

  講了這兩種方式,主要是為了講這兩種方式混用時會出現的問題。如果以action標記了HandleError屬性,同時期所在的controller又重寫了OnException方法,最終會怎樣處理呢?按照mvc中filter的執行順序,controller重寫的方法會被優先執行,不考慮action中的order順序,執行完畢之後再執行action標記的filter的方法。ok,有了這個理論之後,再看看之前提到的情況的執行順序。首先執行OnException中的處理方式,這時候filterContext.ExceptionHandled已經被標記為true了,再執行HandleError屬性的方法時,就不會在被執行了,也就是說自訂的錯誤頁白費了,不起作用。這是因為內建的HandleError在執行的時候會先判斷filterContext.ExceptionHandled是否為true,為true就不執行了,因此會出現一些很奇怪的bug,明白這個道理就知道如何處理了。

       但是總不能把filterContext.ExceptionHandled = true;這行代碼去掉,因為其他action沒有標記handle error屬性,如果不使filterContext.ExceptionHandled為true, 那麼錯誤還是會拋到外層,又交給CustomerError處理了,還是白搭。因此既要保持基類的OnException方法,又要有action自己個人化的錯誤頁,是不能使用系統內建的方式處理,只能自己再去定義ExceptionFilter 了,就是方式三。

 方式三,自訂ExceptionFilter,需要繼承FilterAttribute,和實現IExceptionFilter介面,實現中不需要判斷Exception是否已處理,但要注意需要有AboutError這個action。

 

自訂ExceptionFilter

    public class AboutErrorAttribute : FilterAttribute, IExceptionFilter
    {
        #region IExceptionFilter 成員

        public void OnException(ExceptionContext filterContext)
        {
            UrlHelper url = new UrlHelper(filterContext.RequestContext);
            filterContext.Result = new RedirectResult(url.Action("AboutError", "AboutError"));
        }

        #endregion
    }

 

那麼action中需要改成

View Code

        /// <summary>
        /// 標記自訂的AboutError
        /// </summary>
        /// <returns></returns>
        [AboutError]
        public ActionResult About()
        {
            return View();
        }

 

經過一輪折騰,總算實現了需求,即保證了通用異常被正常處理,個別action個人化的錯誤頁面也能實現,還算比較整潔。但最好架構的HandleError能夠提供是否忽略判斷異常是否已被處理過的屬性設定。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.