ASP.NET MVC下自定義錯誤頁和展示錯誤頁的幾種方式

来源:http://www.cnblogs.com/CKExp/archive/2017/11/19/7859475.html
-Advertisement-
Play Games

在網站運行中,錯誤是不可避免的,錯誤頁的產生也是不可缺少的。 這幾天看了博友的很多文章,自己想總結下我從中學到的和實際中配置的。 首先,需要知道產生錯誤頁的來源,一種是我們的.NET平臺拋出的,一種是網站所依賴的宿主拋出的,一般來講我們所依賴的宿主就是IIS了。 IIS中的錯誤頁入口: 其中的錯誤碼 ...


在網站運行中,錯誤是不可避免的,錯誤頁的產生也是不可缺少的。

這幾天看了博友的很多文章,自己想總結下我從中學到的和實際中配置的。

 

首先,需要知道產生錯誤頁的來源,一種是我們的.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節點時,便是這個方法來幫忙處理。

 

或許還有更多更好的方式。望指導指導,我想學習學習。

 

 

2017-11-19,望技術有成後能回來看見自己的腳步。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 俗話說,沒圖說個JB。好我馬上上圖 提醒:我在這裡只是提供一個思路過程,希望可以幫到你,同時我也做一個記錄,有任何問題歡迎 0、0、:1870194664 威信 :gklbb520 註意:在安裝之前必須要root,小米手機root可能要先解BL鎖 環境:linux deploy 、busybox p ...
  • ch /etc/ chmod 644 passwd group shadow chmod 400 gshadow cd ssh chmod 600 moduli ssh_host_dsa_key ssh_host_key ssh_host_rsa_key chmod 644 ssh_config s ...
  • 說明:系統版本為 Linux version 3.10.0-327.el7.x86_64 step1. 查看現有磁碟信息,可以看出根分區有45G step2. 查看新增加的磁碟信息 step3. 根據以上信息,對新增加的磁碟進行分區 step4. 創建物理捲 step5. 查看物理捲信息 step6 ...
  • PXE概述: PXE(Pre-bootExecution Environment),預啟動執行環境 通過網路介面啟動電腦 支持工作站通過網路從遠端伺服器下載映像,並由此支持通過網路啟動操作系統,在啟動過程中,終端要求伺服器分配IP地址,再用TFTP協議下載一個啟動軟體包到本機記憶體中執行,由這個啟動 ...
  • 查看當前系統資源限制 ulimit -a 設置用戶的最大進程數(重啟後失效) ulimit -u 1024 設置用戶可以打開的最大文件句柄數(重啟後失效) ulimit -n 65530 說明:現在阿裡雲的伺服器一般都會幫你設置好了,還有,上面的方法只是快速修改,不能永久生效,如果想永久生效,就得修 ...
  • 第1章 Rsync開篇介紹 1.1 rsync的定義 Rsync是一款開源的、快速的、多功能的、可實現全量及增量的本地或遠程數據同步備份的優秀工具。Rsync軟體適用於unix/linux/windows等多種操作系統平臺 ① 全量備份:第一次傳輸數據過程中使用全量備份,將全部數據進行傳輸覆蓋 ② ...
  • Server 2008 R2遠程桌面授權,解決120天過期問題 ...
  • 搭建MySQL 1、查看yum庫中的mysql 2、選擇需要的mysql進行安裝 3、驗證是否安裝成功 4、啟動mysql服務 5、進入mysql,並修改密碼 FLUSH PRIVILEGES; //刷新user表,如果沒有寫這句那麼就沒有用 6、退出並用剛修改過的密碼重新登錄 7、開放遠程登錄許可權 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...