找不到自定义错误页面

时间:2010-08-05 16:46:19

标签: asp.net-mvc error-handling custom-errors

以下是我如何定义它(本地,在我的开发机器上):

    <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相同。为什么不能找到它?

3 个答案:

答案 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之类的内容构建自己的自定义过滤器,并将其附加到控制器类。这将完成与上面完全相同的事情,但还有将错误代码发送到客户端的额外好处。

Richard Dingwall talks about it on his blog

答案 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/