ASP.NET MVC,CustomErrors& ResponseRewrite

时间:2014-04-22 19:02:08

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

我有一个MVC网站(v5,虽然我认为它不相关)我在尝试建立数据库连接时故意引入了错误(连接字符串中的服务器IP错误)。当用户点击HomeController时,构造函数的一个依赖项是UserRepository(获取当前用户配置文件数据),这取决于数据库连接/会话是否可用。如果不是,则依赖性解析器无法注入UserRepository,当发生这种情况时会导致错误(与任何控制器的任何依赖关系一样),并且我得到一个通用的“没有为此对象定义的无参数构造函数”。这是没用的。

所以我试图使用自定义错误页面来检索内部异常并以友好的方式显示它。 (因为在尝试获取HomeController时发生此错误,它实际上从未到达HandleErrorAttribute,因此依赖于CustomErrors)。

所以我有一个带有一系列动作的ErrorsController ......

来自ErrorsComtroller.cs的片段

public ActionResult Error()
{
    return View("Error_500");
}

public ActionResult NotFound()
{
    return View("Error_404");
}

来自web.config的片段

<customErrors mode="On">
  <error statusCode="404" redirect="~/errors/notfound" />
  <error statusCode="500" redirect="~/errors/error" />
</customErrors>

Error_500页面非常基本,它的模型类型为HandleErrorInfo,但如果它不存在,则使用Server.GetLastError()检查异常详细信息。问题是,GetLastError()总是为空,我得到了我的自定义错误页面,但没有超出我的“意外错误发生”的一般反馈之外的其他详细信息。在做了一些挖掘后,我发现重定向后该方法不起作用,这是CustomErrors的默认方式。所以我改变了web.config来改为使用这一行......

来自web.config的片段     

这样它就不会导致重定向,GetLastError()应该有关于数据库连接问题的异常详细信息。事情是,现在我得到了带有此消息的默认ASP.NET错误页面。

  

处理您的请求时发生异常。另外,   执行自定义错误页面时发生另一个异常   第一个例外。请求已被终止。

所以我使用intellitrace进行了更多挖掘,我看到了有关数据库连接的异常。稍微向下看,我看到HomeController上没有无参数构造函数的错误,然后是一个关于在尝试创建'HomeController'类型的控制器时遇到错误的错误。但后来我看到一个说

  

执行/ errors / error

的子请求时出错

所以我直接导航到那条路径,页面工作正常。但是当它在带有ResponseRewrite的重定向模式的客户错误中使用时,它会出错。我在ErrorsController.Error()动作的第一行(也是唯一一行)上设置了一个断行,但它永远不会被击中。如果我将自定义错误中的重定向路径替换为静态文件,则可以使用,但如果我将其更改回~/errors/error,则会再次失败。

在指定ResponseRewrite时将MVC操作用作CustomErrors的url时是否存在问题?

1 个答案:

答案 0 :(得分:2)

“发生这种情况是因为”ResponseRewrite“模式使用了封面下的Server.Transfer,它在文件系统上查找文件。因此,您需要将重定向路径更改为静态文件,例如更改为.aspx或.html文件:“

<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/Error.aspx"/>

请参阅:https://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging

“显然,Server.Transfer与MVC路由不兼容,因此,如果您的错误页面由控制器操作提供,Server.Transfer将查找/ Error / Whatever,而不是在文件系统上找到它,并返回一个通用的404错误页面!“

请参阅:CustomErrors does not work when setting redirectMode="ResponseRewrite"

换句话说,您不能将ResponseRewrite与视图一起使用。

这是一个众所周知的问题,对开发人员来说是个问题,因为它无法提供简单或优雅的解决方案。总而言之,MVC在使用自定义视图进行异常处理和客户用户友好页面的HTTP错误时效果不佳。 Views \ Shared文件夹中的stock error.cshtml文件(即View)是一件好事,因为它维护了网页的布局并提供了异常错误。但是,当您收到HTTP错误时,您需要创建一个视图来处理状态代码错误(例如,404,500等)。注意:如果您将HTTP错误发送到视图的路径,则URL行将包含非理想信息(有关详细说明,请参阅下面的网站链接)。

您可以将HTTP错误路由到错误视图,但我不推荐它,因为错误视图应该是应用程序错误(例如,异常),而应该为通用创建单独的自定义用户友好页面HTTP错误。不同之处在于前者是网站开发人员需要关注的应用程序问题,而后者是用户错误(或者至少应该是),不需要开发人员查看它(仅仅是我的2美分)。

另一种方法是绕过视图并使用自定义用户友好页面来处理应用程序异常和HTTP错误。但是,要注意两个问题:

1。)返回错误的状态代码(通常为200),这可能是个问题,因为它会被搜索引擎挑选并编入索引(你不想要这个!)

2。)URL指定Web浏览器中的非敏感URL

这些可以很容易地处理。请参阅以下链接(转到 web.config中的customErrors 部分):https://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging

以下是我发现有用的其他网络链接:

http://benfoster.io/blog/aspnet-mvc-custom-error-pages

https://msdn.microsoft.com/en-us/library/bb397417.aspx

https://www.youtube.com/watch?v=nNEjXCSnw6w

How do I display custom error pages in Asp.Net Mvc 3?

最后一个似乎是另一个选择:一个自定义黑客来解决无法与ResponseRewrite耦合视图的问题。这通过完全绕过CustomErrors(即,CustomErrors mode =“Off”)来工作。我还没有尝试过这个,但我正在研究它。

最后想到,当抛出错误或异常代码时,请密切关注所有站点状态代码 - 确保没有200(即OK)代码。