11

当我的 ASP.NET MVC 4 应用程序发生错误时,我想根据错误类型为用户自定义一个视图。例如,找不到页面或发生异常(带有一些关于异常的用户友好的详细信息)。我已经在 StackOverflow 和其他在线资源上查看了如何执行此操作的其他示例,但没有一个答案对我有用。

基本的 [HandleError] 属性在 VS2012 中似乎不适用于针对 .NET 4.5 的 MVC 4 应用程序。这是我在家庭控制器中的代码:

[HandleError]
public ActionResult Index()
{
    Response.TrySkipIisCustomErrors = true; //doesn't work with or without this
    throw new NullReferenceException("Uh oh, something broke.");
}

它只是抛出一个异常,我希望由于 [HandleError] 属性而返回默认的 ~/Shared/Error.cshtml 视图,但我得到的只是一个 HTTP 500 内部服务器错误,表明该页面无法显示。我检查了我的 web.config,不同的配置似乎表现得很奇怪。在该部分中,它当前包含:

<customErrors mode="On" />

(我尝试添加 defaultRedirect 和 customErrors mode="Off" 但这没有任何效果......共享的错误视图或我拥有的 CustomError 视图都没有被呈现。如果我将 customErrors 模式更改为关闭,然后我可以按预期看到异常详细信息,因此它正确地抛出了“哦,有些东西坏了”异常。

我还尝试将 OnException 处理程序添加到 HomeController,虽然我可以调试并看到 OnException 事件正在引发,但它没有任何区别:

protected override void OnException(ExceptionContext filterContext)
{
    base.OnException(filterContext);
    filterContext.ExceptionHandled = true;
    if (filterContext == null)
    {
        filterContext.Result = View("CustomError");
        return;
    }
    Exception e = filterContext.Exception;
    // TODO: Log the exception here
    ViewData["Exception"] = e; // pass the exception to the view
    filterContext.Result = View("CustomError");
}

我也尝试改变 [HandleError] 来指定一个视图,但这似乎也没有做任何事情:

[HandleError(View="CustomError")]

任何帮助将非常感激。如果您需要更多详细信息,请告诉我。

4

4 回答 4

5

我还继续阅读 SO 答案和各种博客文章,试图让自定义错误页面正常工作。以下是最终对我有用的方法。

第一步是使用 IIS Express 进行调试,而不是使用内置的 Cassini Web 服务器来“保证”调试体验将反映实时环境。

创建一个控制器来处理应用程序错误,并为您要处理的每个自定义错误添加一个操作。该操作应该执行任何日志记录、设置状态代码并返回视图。

public class ErrorsController : Controller
{
    // 404
    [HttpGet]
    public ActionResult NotFound()
    {
        Response.StatusCode = (int)HttpStatusCode.NotFound;
        return View();
    }

    // I also have test actions so that I can verify it's working in production.
    [HttpGet]
    public ActionResult Throw404()
    {
        throw new HttpException((int)HttpStatusCode.NotFound, "demo");
    }
}

配置customErrorsweb.config 中的部分以重定向到您的自定义错误操作。

  <system.web>
    <customErrors mode="RemoteOnly" defaultRedirect="Errors/InternalServerError">
      <error statusCode="400" redirect="Errors/BadRequest" />
      <error statusCode="403" redirect="Errors/Forbidden" />
      <error statusCode="404" redirect="Errors/NotFound" />
      <error statusCode="500" redirect="Errors/InternalServerError" />
    </customErrors>

在 web.config 中添加该httpErrors部分system.webServer并将 errorMode 设置为Detailed。为什么这对我来说是个谜,但这是关键。

  <system.webServer>
    <httpErrors errorMode="Detailed" />

在定义的路由中添加一条包罗万象的路由,以将 404 引导到自定义页面。

            // catchall for 404s
        routes.MapRoute(
            "Error",
            "{*url}",
            new {controller = "Errors", action = "NotFound"});

您可能还想创建一个自定义HandleErrorAttribute并将其注册为全局过滤器以记录 500 错误。

这些步骤在开发(IIS Express)和生产(IIS7)环境中都适用于我。您需要进行更改customErrors mode="On"才能看到开发中的效果。

于 2012-12-12T18:45:05.037 回答
4

我似乎记得您必须从非本地 IP 地址(通常是另一台计算机)调用该页面。而且它必须是基于 IIS 的服务器,而不是内置的开发服务器(所以是 IIS 或 IIS Express,但是您必须配置 IIS Express 以进行外部访问,这很痛苦)。

您实际上可以调试它,您必须在调试计算机上配置本地服务器以接受外部请求,然后从远程服务器调用本地服务器。

于 2012-12-13T01:08:40.877 回答
2

我遇到了类似的问题,并且在试图弄清楚发生了什么事情时迷失了方向。因此,以防万一其他人遇到类似的问题,这就是我的问题所在。

错误页面试图使用我的 _Layout 页面。只要确保你的 Error.cshtml 页面有

@{ 布局 = null; }

于 2014-01-06T21:27:38.560 回答
1

尝试将以下属性添加到customErrors标签:

defaultRedirect="Error"

这明确定义了当抛出错误并且属性中默认没有指定视图时,MVC 应该将用户重定向到哪个视图。这当然只有在视图文件夹Error.cshtml中存在时才有效。Shared

于 2012-12-12T18:35:44.253 回答