如何获取所有局部变量的转储?

How to get a dump of all local variables?

提问人:Skadoosh 提问时间:3/20/2012 最后编辑:Mark RotteveelSkadoosh 更新时间:10/20/2023 访问量:12443

问:

当发生异常时,如何获取所有局部和会话变量的转储?我正在考虑编写某种基于反射的函数,该函数将询问调用函数并创建变量和值的转储。

是否有可以使用的现有库?

在与一位同事交谈后,我被指向了AOP或面向方面的编程。这是我的理解,使用AOP,可以简单地用某些属性来装饰方法和类。然后,AOP 框架在这些类和方法中或周围注入代码。有两种不同的框架,一种是注入代码,然后编译程序集,另一种是简单地使用反射和捕获你修饰的调用,并在运行时将任何代码包装在方法周围。

我希望这一切都是有道理的。我将对此进行更多研究并发布我的方法。

C# asp.net 异常 AOP

评论

0赞 PedroC88 3/20/2012
你使用的是哪个版本的 Visual Studio?(如有)
0赞 Alexei Levenkov 3/21/2012
困难部分(局部变量)是 stackoverflow.com/questions/362124/ 的重复部分,正如Gregory A Beamer所指出的那样。
0赞 Skadoosh 3/21/2012
@PedroC88 - 我正在使用 VS 2010 pro
0赞 PedroC88 3/21/2012
哦。。。我在想 Intellytrace,但它仅在 Ultimate 上可用。

答:

14赞 Tim Schmelter 3/20/2012 #1

我不确定这是否是你要找的。但是,如果你在catch-block中,你可以通过以下方式获取这个类的所有字段和属性:

try
{
    double d = 1 / 0;
}
catch (Exception ex)
{
    var trace = new System.Diagnostics.StackTrace();
    var frame = trace.GetFrame(1);
    var methodName = frame.GetMethod().Name;
    var properties = this.GetType().GetProperties();
    var fields = this.GetType().GetFields(); // public fields
    // for example:
    foreach (var prop in properties)
    {
        var value = prop.GetValue(this, null);
    }
    foreach (var field in fields)
    {
        var value = field.GetValue(this);
    }
    foreach (string key in Session) 
    {
        var value = Session[key];
    }
}

为了完整起见,我已经演示了如何获取发生异常的方法名称。

使用 BindingFlags,您可以指定约束,例如,您只需要此类的属性,而不是继承的属性:

在 .NET Reflection 中将 GetProperties() 与 BindingFlags.DeclaredOnly 一起使用

当然,以上内容应该只给你一个如何手动完成的起点,你应该把所有的东西都封装到类中。我自己从未使用过它,所以它未经测试。

评论

1赞 Pankaj 3/20/2012
this.GetType().GetProperties()给出了 150 个属性的列表,而我的班级中有 1 个属性。 为什么 ?
0赞 Pankaj 3/20/2012
我的意思是,您将如何区分 150 处房产中的罪魁祸首?
0赞 Tim Schmelter 3/20/2012
@PankajGarg:我不知道OP是否想要这150处房产。始终可以指定 BindingFlags。
0赞 Pankaj 3/21/2012
这是一个错误的概念。无需专门用于日志记录的 try catch。只需在此处使用应用程序错误事件和日志消息即可。由于出现错误,全局应用程序级事件进入可见性。
1赞 Tim Schmelter 3/21/2012
@PankajGarg:OP 在哪里提到他想要一个全局错误记录功能?也许他只需要在引发异常的特定情况(类、方法、页面,...)获取所有变量值。我认为您正在混合不同的用例,并将某些内容解读到 OP 的需求中。
0赞 Gregory A Beamer 3/20/2012 #2

这是一个在 Stack Overflow 上令人作呕的问题,尽管措辞不同。在一个线程中,答案是使用 PostSharp。正如其他人建议转储堆栈跟踪一样,您可以这样做。最简单的方法是手动转储局部变量。这可以是 Trace,也可以创建自己的自定义异常处理程序。

1赞 Pankaj 3/21/2012 #3

不应在 Try Catch 窗体中使用异常处理。相反,它应该是

  1. 页面级错误
  2. 应用程序级错误

假设您有一个表示层和一个业务逻辑层/DataAccess 层。

在业务逻辑中遇到错误时,它将直接移动到 Glogal.asax.cs 事件下的 Application_Error 文件,而不会返回调用函数。在这里,您可以记录如下所示的错误消息。

HttpContext.Current.Server.GetLastError().InnerException.StackTrace
HttpContext.Current.Server.GetLastError().InnerException.Message
HttpContext.Current.Server.GetLastError().InnerException.Source
HttpContext.Current.Server.GetLastError().InnerException.TargetSite.DeclaringType.FullName
HttpContext.Current.Server.GetLastError().InnerException.TargetSite.DeclaringType.Name
HttpContext.Current.Server.GetLastError().InnerException.TargetSite.DeclaringType.Namespace

如果出现页面级错误,则 Priority 是 Page OnError 重写,最后是应用程序级错误事件。在这里,您还可以记录错误。

我更喜欢Application_error处理程序,因为如果您有 20 个模块,并且需要为每个模块创建基类。使代码冗余是不好的。

现在,在 Web Config 中,您可以编写代码将用户重定向到某个默认页面,如下所示。

<customErrors defaultRedirect="ErrorPage.htm" mode="On">
   <error statusCode="404" redirect="ErrorPageNotFound.htm"/>
</customErrors>