翻译:ASP.NETMVC自定义错误页面真的简单吗?

如果你在设置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

时间: 2024-08-01 06:29:25

翻译:ASP.NETMVC自定义错误页面真的简单吗?的相关文章

asp.net自定义错误页面

ASP.NET 提供三种用于在出现错误时捕获和响应错误的主要方法:Page_Error 事件.Application_Error 事件以及应用程序配置文件 (Web.config). 如果您不调用 Server.ClearError 或者捕获 Page_Error 或 Application_Error 事件中的错误,则将根据 Web.config 文件的 <customErrors> 部分中的设置处理错误.在 <customErrors> 部分,可将重定向页指定为默认的错误页 (

[转载]针对IIS7以上的ASP.NET网站自定义错误页面与异常日志总结

针对IIS7以上的ASP.NET网站自定义错误页面与异常日志总结 汪宇杰 2014-1-11 星期六 02:31 455 Reads 1 Comments 自定义错误页面和异常记录是个很古老的话题了,但依旧可以让人爆到现在.在我做了无数次试验并总结经验和原则后,写下本文,已警后人. 本文的范围和限制 本文仅仅适用于部署在IIS7或以上版本中的ASP.NET 4.0集成模式应用程序.IIS7以上的意思是Windows Server 2008以上服务器适用.我已在WS2012R2,IIS8上测过.

ASP.NET网站中设置404自定义错误页面

在用ASP.NET WebForm开发一个网站时,需要自定义404错误页面. 做法是这样的 在网站根目录下建立了一个404.html的错误页面,然后在Global.asax文件中,加入如下代码: <%@ Application Language="C#" %> <script runat="server"> void Application_Error(object sender, EventArgs e) { Response.Status

ASP.NET全局错误处理和异常日志记录以及IIS配置自定义错误页面

应用场景和使用目的 很多时候,我们在访问页面的时候,由于程序异常.系统崩溃会导致出现黄页.在通常的情况下,黄页对于我们来说,帮助是极大的,因为它可以帮助我们知道问题根源,甚至是哪一行代码出现了错误.但这对于用户是非常可怕的,因为用户不知道发生了什么,也无法了解黄页给出的内容.甚至,如果我们遇到一些不友好的人,他们会拿这些内容大做文章,对我们网站产生威胁. 那我们如何在程序异常.系统崩溃时,不会出现黄页,并且还可以给出一些更加友好的提示呢?甚至在我们需要的时候,可以收集这些异常信息,并加以分析,能

ASP.NET Core中显示自定义错误页面

在 ASP.NET Core 中,默认情况下当发生500或404错误时,只返回http状态码,不返回任何内容,页面一片空白. 如果在 Startup.cs 的 Configure() 中加上 app.UseStatusCodePages(); ,500错误时依然是一片空白(不知为何对500错误不起作用),404错误时有所改观,页面会显示下面的文字: Status Code: 404; Not Found 如果我们想不管500还是404错误都显示友好的自定义错误页面,该如何实现呢?请看下面的分解.

ASP.NET MVC 自定义错误页面心得

自定义错误页面的目的,就是为了能让程序在出现错误/异常的时候,能够有较好的显示体验. 所以,首先要先了解,我们可以在哪里捕获异常. 当程序发生错误的时候,我们可以在两个地方捕获: Global里面的Application_Error . HandleErrorAttribute 中的OnException.(需要新建一个类,继承HandleErrorAttribute) 那我们到底应该在哪里处理错误好呢?下面我来给大家说说他们的区别. Application_Error 程序中发生的所有异常,都

MVC4 自定义错误页面(三)

一.概述 MVC4框架自带了定义错误页,该页面位于Shared/Error,该页面能够显示系统未能捕获的异常,如何才能使用该页面: 二.使用步骤: 1.配置WebConfig文件,在System.Web节点下加上 <customErrors mode="On"  defaultRedirect="~/Shared/Error" /> 翻阅一些大神写的博客,在他们的博客中指出defaultRedirect是指向错误页面的URL,可是经过本人测试的时候,发现

MVC4 自定义错误页面(转)

一.概述 MVC4框架自带了定义错误页,该页面位于Shared/Error,该页面能够显示系统未能捕获的异常,如何才能使用该页面: 二.使用步骤: 1.配置WebConfig文件,在System.Web节点下加上 <customErrors mode="On"  defaultRedirect="~/Shared/Error" /> 翻阅一些大神写的博客,在他们的博客中指出defaultRedirect是指向错误页面的URL,可是经过本人测试的时候,发现

.net自定义错误页面实现升级篇

问题描述: 在上一篇博文 ".net自定义错误页面实现" 中已经介绍了在.net中如何实现自定义错误页面实现(有需要者可以去上一篇博文了解),单纯按照上一篇博文那样设置,能够实现所有请求的异常自定义跳转,但是这样又会产生一个问题:当通过ajax提交请求获取接口提交请求,如果出现未处理的异常也会被重定向到自定义错误页面. 针对ajax请求或者接口请求,这样返回一个重定向页面,用户体验显然不是太友好,针对这个问题,下面简单总结一下我自己的想法和解决方案,当然不一定科学和合理,所以也希望有大