ASP.NET MVC 4 - 异常处理不起作用

Rob*_*ker 11 asp.net-mvc exception-handling asp.net-mvc-4

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

VS2012中的基本[HandleError]属性似乎不适用于面向.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.");
}
Run Code Online (Sandbox Code Playgroud)

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

<customErrors mode="On" />
Run Code Online (Sandbox Code Playgroud)

(我已经尝试添加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");
}
Run Code Online (Sandbox Code Playgroud)

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

[HandleError(View="CustomError")]
Run Code Online (Sandbox Code Playgroud)

任何帮助将非常感激.如果您需要更多详细信息,请与我们联系.

Jam*_*Ide 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");
    }
}
Run Code Online (Sandbox Code Playgroud)

配置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>
Run Code Online (Sandbox Code Playgroud)

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

  <system.webServer>
    <httpErrors errorMode="Detailed" />
Run Code Online (Sandbox Code Playgroud)

在最后定义的路由中添加一个catchall路由,以将404定向到自定义页面.

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

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

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


Eri*_*sch 4

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

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

  • 尽管我没有在 web.config 中的任何地方使用“RemoteOnly”,但我的原始代码似乎可以远程工作,只是不能在本地工作!这让我感到非常惊讶。我确实必须在 web.config 的 `&lt;system.webserver&gt;` 部分添加 `&lt;modules runAllManagedModulesForAllRequests="true" /&gt;` 才能渲染视图,但这似乎很正常。这使得本地调试变得更加困难,并且看起来像是一个错误,因为没有使用“mode=RemoteOnly”。如果有人知道如何让它在本地工作,请告诉我。(我可能会专门为此提出第二个问题。) (2认同)