ASP.NETMVC自定义错误页面真的简单吗?
Note:文章前半部分翻译自 http://benfoster.io/blog/aspnet-mvc-custom-error-pages ,着急的可直接看总结~
如果你在设置asp.net mvc自定义错误页面时遇到问题,这并不止你一个人。惊讶之余你的做法是正确的,没有起到作用的原因是其一部分错误是由asp.net管道处理的,另一部分是由iis直接处理。
<customErrors mode="On">
<error code="" path="404.html" />
<error code="" 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="" 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="" 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 = %>
我们现在得到了正确的状态码、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=""/>
<error statusCode="" path="/404.html" responseMode="ExecuteURL"/>
</httpErrors>
同样设置 errorMode="Custom"
以便本地测试. 正常情况会设置为 errorMode="DetailedLocalOnly"
.
注意我使用了html页面,而不是aspx。通常你应该用简单的静态文件作为错误页面,这样即使ASP.NET出现错误时错误页面依然能够正常显示。
现在如果我们导航到一个不存在的静态文件路径就会得到一个自定义错误页面而不是IIS默认的404 page,剩下的还是和之前一样的200问题。
<error statusCode="" 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="" redirect="~/404.aspx"/>
<error statusCode="" redirect="~/500.aspx"/>
</customErrors>
类似于前面创建的404.aspx:
<% Response.StatusCode = %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title> Server Error</title>
</head>
<body>
<h1> Server Error</h1>
</body>
</html>
不幸的是这样做并不会捕获到你应用程序中的每一个异常。一个相当常见的错误——由 ASP.NET 产生的请求的验证,如一个危险的url路径/foo/bar<script></script>
,这个实际上会产生一个404响应;因此你可以添加一个默认错误配置:
<customErrors mode="Off" redirectMode="ResponseRewrite" defaultRedirect="~/500.aspx">
<error statusCode="" redirect="~/404.aspx"/>
<error statusCode="" redirect="~/500.aspx"/>
</customErrors>
最后为了捕获非ASP.NET异常我们设置IIS自定义服务器内部错误500错误页面:
<error statusCode="" path="500.html" responseMode="File"/>
总结
在你的应用程序根目录创建如下错误页面:
- 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="" redirect="~/404.aspx"/>
<error statusCode="" redirect="~/500.aspx"/>
</customErrors>配置IIS自定义错误页:
<httpErrors errorMode="DetailedLocalOnly">
<remove statusCode=""/>
<error statusCode="" path="404.html" responseMode="File"/>
<remove statusCode=""/>
<error statusCode="" path="500.html" responseMode="File"/>
</httpErrors>
以上是翻译
另一种不需要 <httpErrors> 配置节的做法是在 <system.webServer> 配置节加入 <modules runAllManagedModulesForAllRequests="true" /> ,这句的作用是让以 .html 结尾的url请求在找不到对应的html静态文件后也能交由asp.net处理(MVC设置伪静态路由就需要这句),缺点也很明显,类似 http://*****.css 的请求在找不到相应的文件时iis也会让其去asp.net管道走一遭。
ASP.NETMVC自定义错误页面真的简单吗?的更多相关文章
- ASP.NET自定义错误页面
ASP.NET自定义错误页面 ASP.NET 提供三种用于在出现错误时捕获和响应错误的主要方法:Page_Error 事件.Application_Error 事件以及应用程序配置文件 (Web.co ...
- ASP.NET网站中设置404自定义错误页面
在用ASP.NET WebForm开发一个网站时,需要自定义404错误页面. 做法是这样的 在网站根目录下建立了一个404.html的错误页面,然后在Global.asax文件中,加入如下代码: &l ...
- 基于 ASP.NET Core 2.1 的 Razor Class Library 实现自定义错误页面的公用类库
注意:文中使用的是 razor pages ,建议使用 razor views ,使用 razor pages 有一个小坑,razor pages 会用到 {page} 路由参数,如果应用中也用到了这 ...
- 新西兰程序员 ASP.NET网站中设置404自定义错误页面
新西兰程序员 ASP.NET网站中设置404自定义错误页面 在用ASP.NET WebForm开发一个网站时,需要自定义404错误页面. 做法是这样的 在网站根目录下建立了一个404.html的错误页 ...
- ASP.NET Core中显示自定义错误页面-增强版
之前的博文 ASP.NET Core中显示自定义错误页面 中的方法是在项目中硬编码实现的,当有多个项目时,就会造成不同项目之间的重复代码,不可取. 在这篇博文中改用middleware实现,并且放在独 ...
- ASP.NET Core中显示自定义错误页面
在 ASP.NET Core 中,默认情况下当发生500或404错误时,只返回http状态码,不返回任何内容,页面一片空白. 如果在 Startup.cs 的 Configure() 中加上 app. ...
- ASP.NET全局错误处理和异常日志记录以及IIS配置自定义错误页面
应用场景和使用目的 很多时候,我们在访问页面的时候,由于程序异常.系统崩溃会导致出现黄页.在通常的情况下,黄页对于我们来说,帮助是极大的,因为它可以帮助我们知道问题根源,甚至是哪一行代码出现了错误.但 ...
- ASP.NET MVC 自定义错误页面心得
自定义错误页面的目的,就是为了能让程序在出现错误/异常的时候,能够有较好的显示体验. 所以,首先要先了解,我们可以在哪里捕获异常. 当程序发生错误的时候,我们可以在两个地方捕获: Global里面的A ...
- MVC4 自定义错误页面(转)
一.概述 MVC4框架自带了定义错误页,该页面位于Shared/Error,该页面能够显示系统未能捕获的异常,如何才能使用该页面: 二.使用步骤: 1.配置WebConfig文件,在System.We ...
随机推荐
- readline,readlines,read函数
readline是读取每一行,包括'\n'.读出来是一个含'\n'的字符串. realines是读取整个文件,返回所有行的一个list(写代码的时候你需要一个文件的某几行,就可以用这个函数去切分) r ...
- Javascript > Eclipse > 自动代码规范化
Reference: http://blog.csdn.net/jmyue/article/details/11060003 大项目往往是有很多人一起完成的,然而每个人都有自己的style,导致整个项 ...
- NSValue 类的使用
NSValue对象是用来存储一个C或者Objective-C数据的简单容器.它可以保存任意类型的数据int,float,char等,也可以是指pointers, structures, and obj ...
- this的用法
因为循环是非常快的,我们手动点击的时候,for循环已经循环完了.如果在循环里面添加点击事件,点击事件的i的值就是循环结果的那个值,而不是对应的循环的值,此时,我们就需要用到this 来实现 点击 ...
- 浅谈一下关于使用css3来制作圆环进度条
最近PC端项目要做一个这样的页面出来,其他的都很简单,关键在于百分比的圆环效果.我最初打算是直接使用canvas来实现的,因为canvas实现一个圆是很简便的. 下面贴出canvas实现圆环的代码,有 ...
- session失效
今天写页面时,使用了session 设置session后 跳转页面session就丢失 上网查了一下也没有很好的解决办法 也没有说原因. 在自己本地电脑上写了两个页面测试一下,完全正常.但是上传到服务 ...
- js 获取URL传递过来的值
URL: http://127.0.0.1:8080/jspews/pews/inspection/InspectCheckCard.jsp?checkDate=2015-03-31 传递的值: ch ...
- [经验] Win7减肥攻略(删文件不删功能、简化优化系统不简优化性能)
[经验] Win7减肥攻略(删文件不删功能.简化优化系统不简优化性能) ☆心梦无痕☆ 发表于 2014-1-24 11:15:04 https://www.itsk.com/thread-316471 ...
- Spring中servletFileUpload完成上传文件以及文本的处理
JSP: <%@ page language="java" contentType="text/html; charset=UTF-8" pageEnco ...
- Rdseed与SAC的安装
欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...