如果你在設定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 的
<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加入如下部分:
我們現在得到了正確的狀態碼、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
<httpErrors errorMode="Custom"> <remove statusCode="404"/> <error statusCode="404" path="/404.html" responseMode="ExecuteURL"/> </httpErrors>
同樣設定errorMode="Custom" 以便本地測試. 正常情況會設定為errorMode="DetailedLocalOnly".
通常你應該用簡單的靜態檔案作為錯誤頁面,這樣即使ASP.NET出現錯誤時錯誤頁面仍然能夠正常顯示。
現在如果我們導航到一個不存在的靜態檔案路徑就會得到一個自訂錯誤頁面而不是IIS預設的404 page,剩下的還是和之前一樣的200問題。
幸運的是IIS 實際上提供了內建的解決方案來解決這一點,如果你設定responseMode ="File"IIS 將返回您的自訂錯誤頁面,而不改變原始的回應標頭︰
搞定。
自訂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/bar3f1c4e4b6b16bbbd69b2ee476dc4f83a2cacc6d41bbb37262a98f745aa00fbf0 ,这个实际上会产生一个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错误页面:
3b10f7d8ee3c92e519d014c43734687b
总结
在你的应用程序根目录创建如下错误页面:
404.html - for IIS
404.aspx - for ASP.NET
500.html - for IIS
500.aspx - for ASP.NET
确认您设置在 ASPX 页面内的适当响应状态码.
抛弃 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>
配置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>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持PHP中文网。
更多ASP.NET MVC自定义错误页面相关文章请关注PHP中文网!