The /Views/Shared/Error.cshtml view (View) file for the ASP.NET MVC 5 project templates from Visual Studio 2017 all the way to Visual Studio 2022 is wrong. When I was teaching the ASP.NET MVC 5 course, I had to Google the full example of this file or look for a version I had written before. Today’s article explains the problem and provides a complete example program for me to quickly find the correct Error View file in the future.

Problem Description

When you create an ASP.NET MVC 5 project template in Visual Studio, the /Views/Shared/Error.cshtml file contains the following.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!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>

Note: The <hgroup> is not a legal HTML5 tag, so it should be removed! 🔥

If your Web.config’s <customErrors> is set to mode="On".

1
2
3
  <system.web>
    <customErrors mode="On"></customErrors>
  </system.web>

When any exceptions occur in your Controller, the rendered HTML is output with the contents of the Layout and Error view pages, and the result looks like this.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<!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>&copy; 2022 - 我的 ASP.NET 應用程式</p>
        </footer>
    </div>

    <script src="/Scripts/jquery-3.4.1.js"></script>

    <script src="/Scripts/bootstrap.js"></script>


</body>
</html>

This means that there are two copies of the final HTML. Every time I see this result, I feel very dumbfounded. Because there is no new version of ASP.NET MVC 5 anymore!

NET Core MVC has been solved.

Solution

So, the correct /Views/Shared/Error.cshtml file should look like this.

1
2
3
4
@model HandleErrorInfo

<h1>錯誤。</h1>
<h2>處理您的要求時發生錯誤。</h2>

Here @model HandleErrorInfo is the Model that can get the error information when the Error error page is displayed, and it is the Model that should be used to get the exception information in the Error View view page. For example, you can use the following method to get the exception message content.

1
2
3
4
5
6
@model HandleErrorInfo

<h1>錯誤。</h1>
<h2>處理您的要求時發生錯誤。</h2>

<pre>@Model.Exception.Message</pre>

For a more complete example of error message display, you can refer to the following code snippet.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
@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>