以下是我如何定义它(本地,在我的开发机器上):
<customErrors mode="On" defaultRedirect="Error.aspx">
<error statusCode="404" redirect="NotFound.aspx" />
</customErrors>
我有[HandleError]属性:
[Authorize]
[HandleError]
public class HomeController : Controller
{ // etc.
然而,当我输入http://localhost:1986/blah时,我收到以下错误:
无法找到资源。 说明:HTTP 404.您要查找的资源(或其中一个依赖项)可能已被删除,名称已更改或暂时不可用。请查看以下网址,确保拼写正确。
请求的网址:/NotFound.aspx
它试图访问的网址正如您所期望的那样: http://localhost:1986/NotFound.aspx?aspxerrorpath=/blah
所以它试图转到自定义错误文件 - 但它无法找到它。我在共享目录中有NotFound.aspx - 与Microsoft默认提供的Error.aspx相同。为什么不能找到它?
答案 0 :(得分:3)
如果Error.aspx和NotFound.aspx在共享目录中,是否有连接的控制器为它们提供服务?如果您没有配置某种控制器路由来提供文件,那么它们在共享文件夹中的事实就无关紧要了。
您有几个选项,您可以创建一个ErrorController,它将处理对这些视图的请求并定义指向这些控制器操作的路由:
[OutputCache(CacheProfile = "Default", VaryByParam = "none")]
public class ErrorController : DefaultAreaBaseController
{
public ViewResult ServiceUnavailable() {
Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
return View("ServiceUnavailable");
}
public ViewResult ServerError() {
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return View("ServerError");
}
public new ViewResult NotFound() {
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View("NotFound");
}
}
或者作为替代方案,您可以创建指向物理文件的忽略路由,并将错误页面放在Views文件夹以外的位置(如根目录):
routes.IgnoreRoute("Error.aspx/{*pathInfo}");
routes.IgnoreRoute("NotFound.aspx/{*pathInfo}");
这些解决方案中的任何一个都是可行的,但是根据您使用IgnoreRoute()的配置可能更为理想,因为它将放弃将请求传递给MVC仅用于提供静态错误页面的需要。
答案 1 :(得分:3)
是构建一个带有“NotFound”视图的错误控制器以及一个“未知”视图。这将采取任何500服务器错误或404 NotFound错误并将您重定向到适当的URL。我并不完全喜欢这个解决方案,因为访问者总是被重定向到错误页面。
http://example.com/Error/Unknown
<customErrors mode="On" defaultRedirect="Error/Unknown">
<error statusCode="404" redirect="Error/NotFound" />
<error statusCode="500" redirect="Error/Unknown" />
</customErrors>
- 的wwwroot /
- 控制器
- Error.cs
- 查看/
- 错误/
- NotFound.aspx
- Unknown.aspx
我绝对不喜欢这种方法(因为它基本上还原为web表单,第二种选择是简单地使用静态Error.aspx页面并忽略MVC中的路由),但它仍然有效。你在这里做的是忽略一个“静态”目录,将你的物理错误页放在那里,然后绕过MVC。
routes.IgnoreRoute("/Static/{*pathInfo}"); //This will ignore everything in the "Static" directory
- 的wwwroot /
- 控制器/
- 静态/
- Error.aspx
- 查看/
第三个选项(这是我最喜欢的)是从任何捕获错误的视图返回错误视图。这将要求您在“已知”错误的过程中编写Try / Catch块,然后您可以使用HandleError来处理可能出现的未知错误。这样做是保留最初请求的URL,但返回ERROR视图。
例:
http://example.com/Products/1234将显示ProductID 1234的详细信息页面
http://example.com/Products/9999会显示 NotFound 错误页面,因为ProductID 9999不存在
http://example.com/Errors/NotFound“应该”永远不会显示,因为您在控制器中单独处理这些错误。
Web.Config
<customErrors mode="On">
</customErrors>
控制器
// Use as many or as few of these as you need
[HandleError(ExceptionType = typeof(SqlException), View = "SqlError")]
[HandleError(ExceptionType = typeof(NullReferenceException), View = "NullError")]
[HandleError(ExceptionType = typeof(SecurityException), View = "SecurityError")]
[HandleError(ExceptionType = typeof(ResourceNotFoundException), View = "NotFound")]
Public Class ProductController: Controller{
public ViewResult Item(string itemID)
{
try
{
Item item = ItemRepository.GetItem(itemID);
return View(item);
}
catch()
{
return View("NotFound");
}
}
}
文件夹结构
- 的wwwroot /
- 控制器/
- 共享/
- NotFound.aspx
- NullError.aspx
- SecurityError.aspx
- SqlError.aspx
- 查看/
最后一个选项是为ResourceNotFoundException
之类的内容构建自己的自定义过滤器,并将其附加到控制器类。这将完成与上面完全相同的事情,但还有将错误代码发送到客户端的额外好处。
答案 2 :(得分:0)
您的混合网络表单和MVC概念。在web.config中关闭自定义错误。然后在HandleError属性中可选地指定类型和视图,默认情况下在views \ CurrentController中搜索error.aspx,然后在views \ shared中搜索。虽然您可以使用HandleError过滤器进行404处理,但您可能只想为404处理创建过滤器,原因以及如何在此处详细说明:
http://richarddingwall.name/2008/08/17/strategies-for-resource-based-404-errors-in-aspnet-mvc/