翻譯:ASP.NETMVC自定義錯誤頁面真的簡單嗎?

来源:http://www.cnblogs.com/CameronWu/archive/2016/10/06/aspnet-mvc-custom-error-pages.html
-Advertisement-
Play Games

如果你在設置asp.net mvc自定義錯誤頁面時遇到問題,這並不止你一個人。驚訝之餘你的做法是正確的,沒有起到作用的原因是其一部分錯誤是由asp.net管道處理的,另一部分是由iis直接處理。 通常情況 (我期望是這種情況,在一些其他框架/伺服器上) 我們只需要在一個地方配置自定義錯誤頁就可以了, ...


如果你在設置asp.net mvc自定義錯誤頁面時遇到問題,這並不止你一個人。驚訝之餘你的做法是正確的,沒有起到作用的原因是其一部分錯誤是由asp.net管道處理的,另一部分是由iis直接處理。

通常情況 期望情況,在一些其他框架/伺服器上) 我們只需要一個地方配置自定義錯誤頁就可以了無論怎麼哪兒引發錯誤像這樣
<customErrors mode="On">
    <error code="404" path="404.html" />
    <error code="500" path="500.html" />
</customErrors>

自定義404錯誤頁面

當一個資源不存在時(包含靜態和動態),我們需要返回一個404狀態的頁面,通常我們需要提供一些稍微友好的信息替代asp.net/iis生成的預設錯誤頁呈現給我們的網站訪問者,可能是提出一些忠告 為什麼資源可能存在提供選擇搜索網站。

這裡僅作演示簡單設置如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8"/>
    <title>404 Page Not Found</title>
</head>
<body>
    <h1>404 Page Not Found</h1>
</body>
</html>

我創建了一個新的ASP.NET MVC 5應用程式,包含vs自帶的標準模版。如果我運行它嘗試導航到一個不存在的路徑 e.g. /foo/bar,就會得到一個包含如下信息的標準 ASP.NET 404 頁面:、

不太友好不是?

這種情況的錯誤是由ASP.NET MVC引發因為它沒有找到與url相匹配的controller或action。

為了自定義404錯誤頁面,在web.config 的 <system.web></system.web>配置節

<customErrors mode="On">
  <error statusCode="404" redirect="~/404.html"/>
</customErrors> 

mode="On" 這樣我們就能在本地看到錯誤頁面。一般你可能只想在投入使用時呈現而設置為 mode="RemoteOnly"。

現在如果我再次導航到/foo/bar 就能看到我剛剛定義的錯誤頁面.

然而正如我所料,此時的url路徑並不是 /foo/bar ASP.NET 將其重定向為/404.html?aspxerrorpath=/foo/bar,而且檢查響應HTTP狀態碼也為正常狀態的200

這是非常糟糕的,返回http code 200不僅會引起誤解,也不利於SEO。簡單來講,如果指定路徑的資源不存在應該返回404如果是資源被移動應該重定向到新路徑。

要修複這個問題我們可以更改ASP.NET預設行為 重定向錯誤頁 為 重寫返回(rewrite the response)。

<customErrors mode="On" redirectMode="ResponseRewrite">
  <error statusCode="404" redirect="~/404.html"/>
</customErrors>

然而這並沒有太大的作用(這老外真啰嗦).儘管原Url地址沒有被重定向, ASP.NET 仍然返回的是 200,此外我們自定義錯誤顯示文本。

 

似乎我們不得不返回一個ASP.NET頁面. 如果你之前以為不用再去 *.aspx頁面的話,那我恐怕讓你失望了。

因此將錯誤頁及相應的web.config改為404.aspx之後,url和content type(text/html)都正常了。

但200的問題依然存在. 這個問題微軟官方給出了相應的解決方案——設置頁面的狀態碼. 我們在404.aspx加入如下部分

<% Response.StatusCode = 404 %>

我們現在得到了正確的狀態碼、url及自定義錯誤頁面,就這樣完事兒了嗎?

 錯.

 如果我們鏈接到一個靜態頁路徑(e.g. foo.html) 或一個不匹配我們路由配置的URL (e.g. /foo/bar/foo/bar),我們會看到到一個標準的IIS 404錯誤頁面.

 上述情況繞過了ASP.NET由IIS處理了請求. 當然如果你在controller ation 中 return一個HttpNotFound()也會得到同樣的結果——這是因為MVC只是簡單的設置status code並沒有拋出錯誤,而是將它交給了IIS.

 這種情況我們需要設置iis的錯誤頁面(僅IIS 7+有效).在 web.config <system.webServer></system.webServer>配置節中

<httpErrors errorMode="Custom">
  <remove statusCode="404"/>
  <error statusCode="404" path="/404.html" responseMode="ExecuteURL"/>
</httpErrors>

同樣設置 errorMode="Custom" 以便本地測試. 正常情況會設置為 errorMode="DetailedLocalOnly".

註意我使用了html頁面,而不是aspx。通常你應該用簡單的靜態文件作為錯誤頁面,這樣即使ASP.NET出現錯誤時錯誤頁面依然能夠正常顯示。

現在如果我們導航到一個不存在的靜態文件路徑就會得到一個自定義錯誤頁面而不是IIS預設的404 page,剩下的還是和之前一樣的200問題。

幸運的 IIS 實際上提供內置解決方案解決一點,如果設置 responseMode ="File"IIS 返回自定義錯誤頁面而不改變原始響應標頭
<error statusCode="404" path="404.html" responseMode="File"/>

搞定。

自定義500錯誤頁

 大部分無外乎照搬上面的解決方法,添加一個自定義的500錯誤頁面。這裡有幾點值得註意的地方。

 標準的 ASP.NET MVC模板內置的 HandleErrorAttribute 作為一個全局過濾器。捕獲在ASP.NET MVC管道引發的任何錯誤,並返回一個自定義"錯誤"視圖提供你有在web.config中啟用自定義錯誤。它會尋找 ~/views/{controllerName}/error.cshtml 或 ~ / views/shared/error.cshtml。

如果你使用了過濾器(filter),你需要更新現有的自定義錯誤視圖,並不存在的則需要創建(最好放在views/shared文件夾下)

我沒有看見這個filter有可以設置的屬性值,在 MVC 管道引發的任何異常都會退回到標準的 ASP.NET 錯誤配置頁面,既然你要設置那些**那這裡就用不到這個filter。

添加如下自定義錯誤頁配置:

<customErrors mode="On" redirectMode="ResponseRewrite">
  <error statusCode="404" redirect="~/404.aspx"/>
  <error statusCode="500" redirect="~/500.aspx"/>
</customErrors>

類似於前面創建的404.aspx:

<% Response.StatusCode = 500 %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>500 Server Error</title>
</head>
<body>
    <h1>500 Server Error</h1>
</body>
</html>

 不幸的是這樣做並不會捕獲到你應用程式中的每一個異常。一個相當常見的錯誤——由 ASP.NET 產生的請求的驗證,如一個危險的url路徑/foo/bar<script></script> ,這個實際上會產生一個404響應;因此你可以添加一個預設錯誤配置:

<customErrors mode="Off" redirectMode="ResponseRewrite" defaultRedirect="~/500.aspx">
 <error statusCode="404" redirect="~/404.aspx"/>
 <error statusCode="500" redirect="~/500.aspx"/>
</customErrors>

 最後為了捕獲非ASP.NET異常我們設置IIS自定義伺服器內部錯誤500錯誤頁面:

<error statusCode="500" path="500.html" responseMode="File"/>

 總結

  1. 在你的應用程式根目錄創建如下錯誤頁面:

    • 404.html - for IIS
    • 404.aspx - for ASP.NET
    • 500.html - for IIS
    • 500.aspx - for ASP.NET
  2. 確認您設置在 ASPX 頁面內的適當響應狀態碼.

  3. 拋棄 MVC HandleErrorAttribute 全局篩選器;配置 ASP.NET 的自定義錯誤:

    <customErrors mode="RemoteOnly" redirectMode="ResponseRewrite" defaultRedirect="~/500.aspx">
      <error statusCode="404" redirect="~/404.aspx"/>
      <error statusCode="500" redirect="~/500.aspx"/>
    </customErrors>
  4. 配置IIS自定義錯誤頁:

    <httpErrors errorMode="DetailedLocalOnly">
     <remove statusCode="404"/>
     <error statusCode="404" path="404.html" responseMode="File"/>
     <remove statusCode="500"/>
     <error statusCode="500" path="500.html" responseMode="File"/>
    </httpErrors>

原文鏈接:http://benfoster.io/blog/aspnet-mvc-custom-error-pages


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

-Advertisement-
Play Games
更多相關文章
  • $()函數在大多的JavaScript類庫中都被作為一個選擇器函數來使用,在jQuery中就是。 $(“#id”)通過id來獲取元素,用來代替document.getElementById()函數。紅色函數(JavaScript) $(“tagName”)通過標簽名來獲取元素,用來代替documen ...
  • 1、JQuery對象“ 如: $(‘div’).text("div展示的信息") 可以看成”是一個包含一個dom數組 和 包含所有Jquery方法的容器 2、每當我們調用選擇器方法查找dom樹里的元素時,其實就是把找到的dom元素存入一個JQ對象里的dom數組中,然後再把這個JQ對象返回。 當我們調 ...
  • 多態之抽象類與介面的相似點及不同點,剛學習的一點收穫,或許不是很完整,借鑒看視頻及一些被人寫的文章自己寫的下的一些心得!以便之久複習使用! 一、抽象類 (1) 抽象方法只作聲明,而不包含實現,可以看成是沒有實現體的虛方法 (2) 抽象類不能被實例化 (3) 抽象類可以但不是必須有抽象屬性和抽象方法, ...
  • 多態之抽象類與虛方法的相似點及不同點 : 不同點 1、方法關鍵字不一樣 虛方法的方法關鍵字是:virtual。 抽象類的方法關鍵詞是:abstract 2、基類的方法是否有方法體/實現 虛方法的方法:聲明並實現方法。 抽象類的方法:只作聲明,無方法體/無實現。 共同點 1、子類/派生類都要重寫父類的 ...
  • Web Is JavaScript Single-Threaded? Quill 1.0 – Better Rich Text Editor for Web Apps Next Generation Server Compression With Brotli Debugging With Node... ...
  • 對於新手的我,現在搞不了大項目,只有從小實驗小項目一點一滴做起。今天就把自己寫的猜拳小游戲給大家分享一下。適合新手一起學習。。 using System; using System.Collections.Generic; using System.ComponentModel; using Sys ...
  • web 發展迅猛,技術日新月異層出不窮,web 的安全性同樣是一場持久的攻防戰。而 HTTPS 的普及,為 web 通信構建了更加良好和安全的根基。 ...
  • 我用vs2015寫了個小網站,.Net Framework4.5、 mvc 5,發佈到本機iis上正常,在美橙申請了一個雲虛擬機,發佈過程中遇到的一些問題記錄如下: 1、伺服器支持的版本比較低 上傳後打開網站顯示: HTTP 錯誤 404.0 - Not Found您要找的資源已被刪除、已更名或暫時 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...