從 Visual Studio 2017 一直到 Visual Studio 2022 的 ASP.NET MVC 5 專案範本,其 /Views/Shared/Error.cshtml
檢視 (View) 檔案內容都是錯誤的。之前在講授 ASP.NET MVC 5 課程的時候,每次都要自己 Google 以下這個檔案的完整範例,或是去翻找我之前寫過的版本。今天這篇文章特別將該檔案的問題做個說明,並且提供完整的範例程式,方便我日後快速查找到正確的 Error View 檔案內容。
問題描述
當你透過 Visual Studio 建立 ASP.NET MVC 5 專案範本,其 /Views/Shared/Error.cshtml
檔案內容如下:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width" />
<title>錯誤</title>
</head>
<body>
<hgroup>
<h1>錯誤。</h1>
<h2>處理您的要求時發生錯誤。</h2>
</hgroup>
</body>
</html>
注意:這裡的 <hgroup>
並不是合法的 HTML5 標籤(Tag),所以應該移除才對!🔥
若你的 Web.config 的 <customErrors>
設定為 mode="On"
的話:
<system.web>
<customErrors mode="On"></customErrors>
</system.web>
當你的 Controller 出現任何例外狀況時,呈現的 HTML 會連同 Layout 與 Error 檢視頁面的內容一起輸出,結果長這樣:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> - 我的 ASP.NET 應用程式</title>
<link href="/Content/bootstrap.css" rel="stylesheet"/>
<link href="/Content/site.css" rel="stylesheet"/>
<script src="/Scripts/modernizr-2.8.3.js"></script>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">應用程式名稱</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/">Home</a></li>
<li><a href="/Home/About">關於</a></li>
<li><a href="/Home/Contact">連絡人</a></li>
</ul>
</div>
</div>
</div>
<div class="container body-content">
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width" />
<title>錯誤</title>
</head>
<body>
<hgroup>
<h1>錯誤。</h1>
<h2>處理您的要求時發生錯誤。</h2>
</hgroup>
</body>
</html>
<hr />
<footer>
<p>© 2022 - 我的 ASP.NET 應用程式</p>
</footer>
</div>
<script src="/Scripts/jquery-3.4.1.js"></script>
<script src="/Scripts/bootstrap.js"></script>
</body>
</html>
這意味著最終的 HTML 竟然出現了兩份,每次看到這種結果都覺得很傻眼,微軟怎麼可以放任這個問題這麼多年?因為 ASP.NET MVC 5 已經不會再有新版本了!
這個問題到了 ASP.NET Core MVC 已經有解決。
解決方案
所以,正確的 /Views/Shared/Error.cshtml
檔案內容應該是這樣的:
@model HandleErrorInfo
<h1>錯誤。</h1>
<h2>處理您的要求時發生錯誤。</h2>
這裡的 @model HandleErrorInfo
是當 Error
錯誤頁面顯示時,可以取得錯誤資訊的 Model 型別,在 Error
這個 View 檢視頁面中,就是應該使用這個 Model 來取得例外資訊。例如,你可以使用以下方法取得例外的訊息內容:
@model HandleErrorInfo
<h1>錯誤。</h1>
<h2>處理您的要求時發生錯誤。</h2>
<pre>@Model.Exception.Message</pre>
如果想要參考更完整的錯誤訊息顯示範例,可以參考以下程式碼片段:
@model HandleErrorInfo
<h1>錯誤。</h1>
<h2>處理您的要求時發生錯誤。</h2>
<ul>
<li>
ControllerName
<blockquote>@Model.ControllerName</blockquote>
</li>
<li>
ActionName
<blockquote>@Model.ActionName</blockquote>
</li>
<li>
Exception
<blockquote><pre>@Model.Exception.ToString()</pre></blockquote>
</li>
@{
if (Model.Exception is null)
{
<li>
InnerException
<blockquote>@(Model.Exception.InnerException?.ToString())</blockquote>
</li>
}
}
@{
if (Model.Exception is System.Data.Entity.Validation.DbEntityValidationException ex)
{
<li>
DbEntityValidationException
<blockquote>
<ol>
@foreach (var eves in ex.EntityValidationErrors)
{
foreach (var ves in eves.ValidationErrors)
{
<li>@(ves.PropertyName + ": " + ves.ErrorMessage))</li>
}
}
</ol>
</blockquote>
</li>
}
}
<li>
User
<blockquote>@User.Identity.Name</blockquote>
</li>
<li>
Url
<blockquote>@Request.Url</blockquote>
</li>
<li>
SessionID
<blockquote>@Session.SessionID</blockquote>
</li>
</ul>
相關連結