我一整天都在尝试在我的ASP.NET MVC 2应用程序中实现错误处理。我查看了各种技术,但都不能正常工作。我正在使用MVC2和.NET 4.0(在MVC3发布之前启动了项目;我们将在发布最初版本后升级)。
目前,我希望能够正确处理404和500错误--403(需要授权)也很好,然后是其他特定响应。目前,我要么得到全部404、全部500、在404之前的所有302或在500之前的所有302。
以下是我的要求(这应该非常接近HTTP的基本要求):
如果找不到资源,则抛出404,并显示一个具有请求URL的404特定页面。不要返回像302这样的中间响应代码。理想情况下,保留请求的URL,而不是显示新的URL,如
/Error/NotFound
--但如果后者显示,请确保我们没有返回重定向响应以获取它。如果发生内部服务器错误,则抛出500,并显示一个具有某些出错信息的500特定错误。同样,不要返回中间响应代码,并且理想情况下不要更改URL。
以下是我认为是404的内容:
- 未找到静态文件:
/Content/non-existent-dir/non-existent-file.txt
- 未找到控制器:
/non-existent-controller/Foo/666
- 已找到控制器,但未找到操作:
/Home/non-existent-action/666
- 已找到控制器和操作,但操作无法找到请求的对象:
/Home/Login/non-existent-id
以下是我认为是500的内容:
- 发布错误的值:
POST /User/New/new-user-name-too-long-for-db-column-constraint
- 非数据相关问题,比如Web服务端点不响应
有些问题需要由特定的控制器或模型识别,然后控制器应该抛出适当的 HttpException。其余的问题应该更通用地处理。
对于404情况#2,我试图使用自定义的ControllerFactory在找不到控制器时抛出404错误。
对于404情况#3,我尝试使用自定义基础控制器来覆盖HandleUnknownAction
并抛出404错误。
在这两种情况下,我都会在404之前得到302。而且,我从未遇到500错误;如果我修改Web.config以在我的Web服务端点中放置一个错字,则仍会得到302,然后得到一个404,说找不到使用Web服务的URL(控制器/操作)。
我还将请求的URL作为(不需要的)查询字符串参数获取:/Error/NotFound?aspxerrorpath=/Home/non-existent-action
这两种技术都来自http://www.niksmit.com/wp/?p=17(如何使用ASP.Net MVC获得正常的404(页面未找到)错误页面),它指向了http://richarddingwall.name/2008/08/17/strategies-for-resource-based-404-errors-in-aspnet-mvc/
如果在Web.config中我有<customErrors mode="On" defaultRedirect="~/Error/Unknown" redirectMode="ResponseRedirect" />
,我会得到适当的响应代码,但我的Error控制器永远不会被调用。去掉redirectMode
属性会让我获得MVC错误视图,但会出现一个介入的302和一个更改后的URL——而且始终是同一个控制器(Unknown
= 500;如果我将它更改为NotFound
,则所有都像404)。
以下是我阅读并尝试实施的其他一些内容:
- http://www.davidjuth.com/asp-net-mvc-error-handler.aspx
- http://sanjayuttam.com/wordpress/index.php/c-sharp/c-sharp-code-examples/error-handling-in-asp-net-mvc-1-part-2-of-2/
- http://blog.hebbink.com/post/2010/12/14/NET-custom-404-error-page-returns-302-for-http-status.aspx
- http://blog.dantup.com/2009/04/aspnet-mvc-handleerror-attribute-custom.html
- http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx
与一些 StackOverflow 帖子一起提供给你。
在我看来,这种错误处理对于 Web 应用程序来说相当基本,而 MVC 框架应该具有开箱即用的默认设置,并允许人们扩展它以按其他方式工作。也许他们会在将来的版本中进行改进。与此同时,有人能够详细介绍如何实现正确的 HTTP 响应吗?