If I add the following line to an ASP.NET MVC action method
如果我将以下行添加到ASP.NET MVC操作方法
throw new Exception("outer", new SecurityException("inner"));
the error that is actually displayed on the yellow screen of death is the inner SecurityException with absolutely no mention of the outer exception.
实际显示在死亡黄色屏幕上的错误是内部SecurityException,绝对没有提到外部异常。
SecurityException
Description: The application attempted to perform an operation not allowed by the security policy. To grant this application the required permission please contact your system administrator or change the application's trust level in the configuration file.
说明:应用程序尝试执行安全策略不允许的操作。要授予此应用程序所需的权限,请与系统管理员联系或在配置文件中更改应用程序的信任级别。
Exception Details: System.Security.SecurityException: inner
异常详细信息:System.Security.SecurityException:inner
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
在执行当前Web请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来识别有关异常的起源和位置的信息。
Stack Trace:
[SecurityException: inner]
Is this expected behavior?
这是预期的行为吗?
It doesn't seem to matter what type the outer exception is. Even if it is another SecurityException, the message is never displayed. The default SecurityException error message is so vague that I want to catch it and add some more specific information. This works fine if I do not include the original SecurityException as the innerException but ideally I would like to do this.
外部异常的类型似乎并不重要。即使它是另一个SecurityException,也不会显示该消息。默认的SecurityException错误消息是如此模糊,我想捕获它并添加一些更具体的信息。如果我不将原始的SecurityException包含为innerException,但理想情况下我想这样做,这样可以正常工作。
2 个解决方案
#1
5
This behaviour originates in the ASP.NET "core", not in ASP.NET MVC. Unfortunately, the error formatter classes are internal, and the consuming types do not provide any extension points that would allow one to tweak the behaviour without replacing the error reporting mechanism. The workaround is to replace the default "yellow screen of death" page by a custom error page/view in which one exposes the information that one prefers.
此行为源自ASP.NET“核心”,而不是ASP.NET MVC。不幸的是,错误格式化程序类是内部的,并且消费类型不提供任何扩展点,允许人们在不替换错误报告机制的情况下调整行为。解决方法是通过自定义错误页面/视图替换默认的“黄色死亡屏幕”页面,其中一个公开了一个人喜欢的信息。
This is exactly what one should usually be doing for production. In your case, it just means that you would have an alternate version for debug instead of using the ASP.NET-provided default.
这正是人们通常应该为生产做的事情。在您的情况下,它只是意味着您将有一个备用版本用于调试,而不是使用ASP.NET提供的默认值。
#2
-1
in general you should never throw Exception class/object directly but only derived ones, for example:
通常,您不应该直接抛出Exception类/对象,而只抛出派生类,例如:
throw new SecurityException("user should not be allowed to access this method...");
in a situation like this what are you missing in the log or in the page?
在这种情况下你在日志或页面中缺少什么?
if you use an application global exception handler and you log from there with either Log4Net
or NLog
you should be able to access all exception chain from outer to inner and so on depending on how you configure and use the logging framework. The Yellow page of IIS / ASP.NET might not be complete but should show the stack trace anyway.
如果您使用应用程序全局异常处理程序并使用Log4Net或NLog从那里进行日志记录,则应该能够从外部到内部访问所有异常链,依此类推,具体取决于您如何配置和使用日志记录框架。 IIS / ASP.NET的黄页可能不完整,但无论如何都应显示堆栈跟踪。
if you want to throw your own exception from a catch block you wrap the actual exception coming from the catch in this way:
如果你想从catch块中抛出自己的异常,你可以用这种方式包装来自catch的实际异常:
throw new SecurityException("user should not be allowed...", exc);
Edit: tried what you suggested and got the following logged in a text file by Log4Net:
编辑:尝试了你的建议,并通过Log4Net登录了一个文本文件:
System.Security.SecurityException: more explicit exception ---> System.Security.SecurityException: original exception at EDICheckerApp.Program.boom() in C:\DEV_RPP\Program.cs:line 45
--- End of inner exception stack trace --- at EDICheckerApp.Program.boom() in C:\DEV_RPP\Program.cs:line 49
at EDICheckerApp.Program.Main(String[] args) in C:\DEV_RPP\Program.cs:line 27System.Security.SecurityException:更明确的异常---> System.Security.SecurityException:C:\ DEV_RPP \ Program.cs中EDICheckerApp.Program.boom()的原始异常:第45行---内部异常堆栈跟踪结束---位于C:\ DEV_RPP \ Program.cs中的EDICheckerApp.Program.boom():位于C:\ DEV_RPP \ Program.cs中的EDICheckerApp.Program.Main(String [] args)的第49行:第27行
#1
5
This behaviour originates in the ASP.NET "core", not in ASP.NET MVC. Unfortunately, the error formatter classes are internal, and the consuming types do not provide any extension points that would allow one to tweak the behaviour without replacing the error reporting mechanism. The workaround is to replace the default "yellow screen of death" page by a custom error page/view in which one exposes the information that one prefers.
此行为源自ASP.NET“核心”,而不是ASP.NET MVC。不幸的是,错误格式化程序类是内部的,并且消费类型不提供任何扩展点,允许人们在不替换错误报告机制的情况下调整行为。解决方法是通过自定义错误页面/视图替换默认的“黄色死亡屏幕”页面,其中一个公开了一个人喜欢的信息。
This is exactly what one should usually be doing for production. In your case, it just means that you would have an alternate version for debug instead of using the ASP.NET-provided default.
这正是人们通常应该为生产做的事情。在您的情况下,它只是意味着您将有一个备用版本用于调试,而不是使用ASP.NET提供的默认值。
#2
-1
in general you should never throw Exception class/object directly but only derived ones, for example:
通常,您不应该直接抛出Exception类/对象,而只抛出派生类,例如:
throw new SecurityException("user should not be allowed to access this method...");
in a situation like this what are you missing in the log or in the page?
在这种情况下你在日志或页面中缺少什么?
if you use an application global exception handler and you log from there with either Log4Net
or NLog
you should be able to access all exception chain from outer to inner and so on depending on how you configure and use the logging framework. The Yellow page of IIS / ASP.NET might not be complete but should show the stack trace anyway.
如果您使用应用程序全局异常处理程序并使用Log4Net或NLog从那里进行日志记录,则应该能够从外部到内部访问所有异常链,依此类推,具体取决于您如何配置和使用日志记录框架。 IIS / ASP.NET的黄页可能不完整,但无论如何都应显示堆栈跟踪。
if you want to throw your own exception from a catch block you wrap the actual exception coming from the catch in this way:
如果你想从catch块中抛出自己的异常,你可以用这种方式包装来自catch的实际异常:
throw new SecurityException("user should not be allowed...", exc);
Edit: tried what you suggested and got the following logged in a text file by Log4Net:
编辑:尝试了你的建议,并通过Log4Net登录了一个文本文件:
System.Security.SecurityException: more explicit exception ---> System.Security.SecurityException: original exception at EDICheckerApp.Program.boom() in C:\DEV_RPP\Program.cs:line 45
--- End of inner exception stack trace --- at EDICheckerApp.Program.boom() in C:\DEV_RPP\Program.cs:line 49
at EDICheckerApp.Program.Main(String[] args) in C:\DEV_RPP\Program.cs:line 27System.Security.SecurityException:更明确的异常---> System.Security.SecurityException:C:\ DEV_RPP \ Program.cs中EDICheckerApp.Program.boom()的原始异常:第45行---内部异常堆栈跟踪结束---位于C:\ DEV_RPP \ Program.cs中的EDICheckerApp.Program.boom():位于C:\ DEV_RPP \ Program.cs中的EDICheckerApp.Program.Main(String [] args)的第49行:第27行