- 工信部備案號 滇ICP備05000110號-1
- 滇公安備案 滇53010302000111
- 增值電信業(yè)務(wù)經(jīng)營許可證 B1.B2-20181647、滇B1.B2-20190004
- 云南互聯(lián)網(wǎng)協(xié)會理事單位
- 安全聯(lián)盟認(rèn)證網(wǎng)站身份V標(biāo)記
- 域名注冊服務(wù)機(jī)構(gòu)許可:滇D3-20230001
- 代理域名注冊服務(wù)機(jī)構(gòu):新網(wǎng)數(shù)碼
ASP.NET MVC下自定義錯誤頁和展示錯誤頁的方式
在網(wǎng)站運行中,錯誤是不可避免的,錯誤頁的產(chǎn)生也是不可缺少的。
這幾天看了博友的很多文章,自己想總結(jié)下我從中學(xué)到的和實際中配置的。
首先,需要知道產(chǎn)生錯誤頁的來源,一種是我們的.NET平臺拋出的,一種是網(wǎng)站所依賴的宿主拋出的,一般來講我們所依賴的宿主就是IIS了。
IIS中的錯誤頁入口:
其中的錯誤碼想必并不陌生
這里是在服務(wù)器上找不到所需資源時拋出的錯誤頁,在這里可以設(shè)置需要展示的錯誤頁面,只需將預(yù)定的錯誤頁面加入服務(wù)器中,然后在指定狀態(tài)碼下配置路徑即可。
這是請求在IIS中時,還未完全進(jìn)入到asp.net mvc中,這里需要理解什么是未完全進(jìn)入,IIS7+的版本中,不依賴于請求路徑末尾的標(biāo)識信息,利用mvc中的urlRoutingModule進(jìn)行處理,在我們配置mvc的路由時,首先的第一條:
1 | routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" ); |
便是隔離非mvc內(nèi)部的使用文件,如果請求的只是服務(wù)器上的文件,那么路由便會在這里進(jìn)行過濾,使之不匹配具體路由信息。
也就只是和mvc打了個招呼 然后就走了,沒有進(jìn)入mvc中搞事情。
第二種是,進(jìn)入了asp.net mvc的管轄范圍,然后在其中出錯了,便是跳到我們在程序中配置的錯誤頁了。
首先講講我從博友那里學(xué)到的、看到的幾種方式。
第一種是在web.config中通過customError配置。
1 2 3 | <customErrors mode= "On" defaultRedirect= "~/Error/ErrorPage" > <error statusCode= "404" redirect= "~/Error/ErrorPage404" /> </customErrors> |
但是這種方式不怎么令人接受,太過于簡單,沒有一點異常信息,并且有時候還不能起效果,我不太喜歡這種方式。
這種是用框架封裝好的,利用的是將要說的第三種的強大方式實現(xiàn)的,當(dāng)有異常發(fā)生又沒得捕獲時,最終利用的第三種方式自動實現(xiàn)。
第二種是利用HandlerErrorAttribute 特性,利用AOP的方式,當(dāng)有異常出現(xiàn)時,便會進(jìn)入具體實現(xiàn)了這個特性的,且被注冊了的ExceptionAttribute職責(zé)中。
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... 可以通過這種形勢,將其轉(zhuǎn)移到不同的自定義錯誤頁面上,此處我增加了一個控制器
CustomErrorPageController,專門用來存放錯誤頁面,原有的Shared下的Error.cshtml錯誤頁面也仍然存在著。
我比較喜歡這種方式,一來可以看到異常信息,而來可以設(shè)計需要跳轉(zhuǎn)的錯誤頁面。
第三種方式也是最強大的、俗稱"最后一道防線",從全局層面去捕捉異常的Application_Error
當(dāng)網(wǎng)站初次啟動時,會執(zhí)行一個特殊的動作,Application_start 首先執(zhí)行,也只初始化一次。這個也是Application 中的事件。
// // 摘要: // ASP.NET 將 HTTP 標(biāo)頭發(fā)送到客戶端之前發(fā)生。 public event EventHandler PreSendRequestHeaders; // // 摘要: // 在選擇該處理程序?qū)φ埱笞鞒鲰憫?yīng)時發(fā)生。 public event EventHandler MapRequestHandler; // // 摘要: // 釋放應(yīng)用程序時發(fā)生。 public event EventHandler Disposed; // // 摘要: // 作為執(zhí)行的 HTTP 管道鏈中的第一個事件發(fā)生,當(dāng) ASP.NET 的請求做出響應(yīng)。 public event EventHandler BeginRequest; // // 摘要: // 當(dāng)安全模塊已建立的用戶標(biāo)識時出現(xiàn)。 public event EventHandler AuthenticateRequest; // // 摘要: // 當(dāng)安全模塊已建立的用戶標(biāo)識時出現(xiàn)。 public event EventHandler PostAuthenticateRequest; // // 摘要: // 安全模塊已驗證用戶身份驗證時發(fā)生。 public event EventHandler AuthorizeRequest; // // 摘要: // 當(dāng)前請求的用戶已被授權(quán)時發(fā)生。 public event EventHandler PostAuthorizeRequest; // // 摘要: // 當(dāng) ASP.NET 完成授權(quán)事件以便從緩存中,跳過的事件處理程序 (例如,一個頁面或 XML Web 服務(wù)) 執(zhí)行的請求提供服務(wù)的緩存模塊時發(fā)生。 public event EventHandler ResolveRequestCache;
|