【问题标题】:MVC3 HandleError doesn't show error pageMVC3 HandleError 不显示错误页面
【发布时间】:2011-05-10 08:35:48
【问题描述】:

我一直在关注 HandleError 属性的本指南: blogs.msdn.com 我这样使用(AccountController):

[HandleError(View="ErasErrorPage")]
        public ActionResult Index()
        {
            ViewBag.admins = _accountMapper.GetAdmins(false);
            ViewBag.members = _accountMapper.GetMembers(false);
            ViewBag.Countries = _countryMapper.GetCountries();

            return View();
        }

此代码引发异常,因为 _accountMapper.GetAdmins(false) 由于 System.Data.EntityException 而失败。

我已将 ErasErrorPage 视图放在共享文件夹中,并添加了 <customErrors mode="On"/>,但 ErasErrorPage 未显示。当错误发生时,我得到的只是一个黄色的死亡屏幕,上面写着:

显然,将模式设置为“Off”或“RemoteOnly”并不能解决问题。

有人知道为什么这不起作用吗?


编辑

如果我直接浏览http://localhost:3527/Account/Index,我会得到正确的 ErasErrorPage,但我不希望这样。我希望网站在某处引发异常时自动重定向到该页面。这可能吗?


EDIT2

我已将 [HandleError(View="ErasErrorPage")] 属性放在每个 Public ActionResult methodName() { ... } 方法之前,但我仍然收到黄屏死机说我需要将模式更改为“关闭”或“仅远程”...

【问题讨论】:

  • 这是一个非常古老的问题,但对于偶然发现它的人来说。您必须有 customErrors="On",并且异常必须生成 500 类错误,抛出 403 并且不会触发,它不会处理已处理的子操作或异常,并且异常必须从 System.例外,没有本地人。一个简单的测试方法是简单地删除 View 属性,检查它是否至少触发到默认的错误页面。如果是,您知道它是自定义视图的路径错误等。

标签: c# asp.net asp.net-mvc-3


【解决方案1】:

确保ErasErrorPage 视图本身不会引发异常。以下是我执行的步骤,对我来说效果很好:

  1. 使用默认的 Visual Studio 向导创建一个新的 ASP.NET MVC 3 项目
  2. 添加~/Views/Shared/ErasErrorPage.cshtml,内容如下:

    @{
        Layout = null;
    }
    <!DOCTYPE html>
    <html>
    <head>
        <title>ErasErrorPage</title>
    </head>
    <body>
        <div>
            OOPS
        </div>
    </body>
    </html>
    
  3. 将 HomeContoller 修改为如下所示:

    public class HomeController : Controller
    {
        [HandleError(View = "ErasErrorPage")]
        public ActionResult Index()
        {
            throw new Exception("oops");
        }
    }
    
  4. 在 web.config 中放置:

    <customErrors mode="On" />
    
  5. 导航到/Home/Index =>自定义错误页面按预期显示

【讨论】:

  • @Matthias,您仅使用此属性修饰了 Index 操作。如果您想将此自定义错误页面用于所有操作,您可以编写自定义句柄错误属性并将其注册为全局过滤器,或者拥有一个基本控制器,您的所有控制器都从该控制器派生并装饰此控制器。
  • @Darin:是的,我认为这可能会起作用......你能举个例子来说明如何做到这一点吗?因为我不需要在所有 ActionResult 方法之上添加 [CustomError] 属性吗?
  • @Mathias,不,你会在Global.asaxRegisterGlobalFilters 方法中执行此操作。这会将其注册为全局过滤器,从而自动应用于应用程序中的所有操作。因此,只需将默认值替换为以下行:filters.Add(new HandleErrorAttribute() { View = "ErasErrorPage" });,您就可以开始了。不再需要使用 [HandleError(View = "ErasErrorPage")] 属性手动装饰控制器操作。
  • 不,对不起...我仍然得到相同的 YSOD。
  • @Matthias,ErasErrorPage.cshtml 包含什么?您是否尝试过使用我在回答中显示的非常简单的模板?
【解决方案2】:

由于这根本不起作用,我找到了一个很好的替代方案:

Custom error pages on asp.net MVC3

我也发现了失败的原因:

我们在尝试渲染视图之前尝试连接到数据库。 HandleError 属性甚至不会被触发(我认为)。上面的方法确实做到了。它可以随时随地处理任何异常。

【讨论】:

    【解决方案3】:

    它确实有效,我有一个带有属性 [HandleError(View = "Error")] 的 BaseController 和一个与动态模型共享的错误视图(应该是 HandleErrorInfo),并且在 HomeController 的 Index 操作中我抛出了一个异常:

    throw new Exception("Test exception");
    

    然后呈现错误视图并显示正确的信息。

    错误视图:

    <div class="errorMessage">
        <h1 class="errorHeader">@Model.Exception.GetType().Name</h1>
        <cite class="errorAction">thrown in @Model.ControllerName @Model.ActionName</cite>
        <p class="errorMessage">thrown in @Model.Message</p>
    </div>
    

    【讨论】:

    • This comment was a suggested edit from someone: 编辑因为我无法评论:我可以验证这对我也有效,但前提是我在自定义错误视图中设置了Response.StatusCode = (int)HttpStatusCode.OK;。否则,即使生成了 ErrorView 中的视图,响应也会替换为通用的 500 错误页面。
    猜你喜欢
    • 2011-11-06
    • 2011-06-21
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多