ASP.NET MVC,CustomErrors和ResponseRewrite

Nic*_*cht 5 asp.net error-handling asp.net-mvc 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");
}
Run Code Online (Sandbox Code Playgroud)

来自web.config的代码段

<customErrors mode="On">
  <error statusCode="404" redirect="~/errors/notfound" />
  <error statusCode="500" redirect="~/errors/error" />
</customErrors>
Run Code Online (Sandbox Code Playgroud)

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

来自web.config的代码段

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

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

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

执行/ errors/error的子请求时出错

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

当指定使用MVC操作作为CustomErrors的url时是否存在问题ResponseRewrite

J W*_*ezy 4

“发生这种情况是因为“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 错误页面!”

请参阅:设置redirectMode =“ResponseRewrite”时CustomErrors不起作用

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

这是一个众所周知的问题,一直困扰着开发人员,因为它没有提供简单或优雅的解决方案。底线是,当使用自定义视图进行异常处理和使用客户用户友好的页面处理 HTTP 错误时,MVC 效果不佳。Views\Shared 文件夹中的stock error.cshtml 文件(即视图)是一个很棒的东西,因为它维护网页的布局并提供异常错误。但是,当您收到 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

如何在 Asp.Net Mvc 3 中显示自定义错误页面?

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

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