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



当ASP.NET MVC 4应用程序中发生错误时,我希望根据错误类型为用户自定义视图。例如,找不到页面或发生异常(包含一些用户友好的异常详细信息)。我已经在StackOverflow和其他在线资源上查看了如何做到这一点的其他例子,但没有一个答案对我有效

在以.NET 4.5为目标的MVC 4应用程序的VS2012中,基本的[HandleError]属性似乎不起作用。这是我的家庭控制器中的代码:

[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视图都没有被呈现。如果我将CustomError模式更改为Off,那么我可以看到预期的异常详细信息,所以它正确地抛出了"哦,有东西坏了"异常。

我还尝试在HomeController中添加一个OnException处理程序,尽管我可以调试并看到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")]

任何帮助都将不胜感激。如果你需要更多的细节,请告诉我。

我还经历了一段无尽的阅读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");
}
}

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

<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>

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

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

将catchall路由最后添加到定义的路由,以将404引导到自定义页面。

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

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

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

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

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

我遇到了一个类似的问题,在试图弄清楚发生了什么的过程中损失了一段时间。所以,为了防止其他人遇到类似的问题。这里就是我的问题。

错误页面试图使用我的布局页面(_L)。只需确保您的Error.cshtml页面具有

@{Layout=null;}

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

defaultRedirect="Error"

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

最新更新