从StackTrace中过滤掉非用户代码方法

Nev*_*ing 6 .net c# asp.net

我正在尝试实现更复杂的错误处理.为了实现我的目标,我需要从curent StackTrace中过滤掉非用户代码方法(框架).

在ASP.NET典型的StackTrace中,您可能会猜到许多方法与调试目的无关,因为它们不在用户代码中.Visual Studio为您提供了筛选出这个非用户代码(框架)的选项,因此我猜它是可能的.然而,在探索StackFrames(以及方法,模块,程序集......)的方法和属性大约30分钟后,我找不到任何可用于识别"系统"框架的东西.

我最终手动指定了我要记录的模块(模块是程序集的一部分,在我的例子中是1:1).

有没有更好的方法来做到这一点?只需包含核心ASP.NET之外的所有内容

Adr*_*tti 6

StackFrameclass具有GetMethod()成员函数,来自检索MethodBase对象.

如果您只需要一个天真的过滤器,您可以执行以下操作之一:

  • 删除以"System"开头的类中的每个方法.或"微软".(因为所有的.NET库都放在那里).
  • 找到方法所在的程序集(参见前进),然后检查AssemblyCompanyAttribute并过滤"Microsoft Corporation"生成的程序集.这比以前的方法更好,因为有时候我看到了将自己的类型放在System命名空间中的库.

如果您需要更多内容,可以获取MethodBase.Module定义该方法的module().现在您有两个选择:

  • 如果所有程序集都已签名,则只能显示具有该公钥令牌的方法(获取使用Module.Assembly属性定义模块的程序集,构建AssemblyName对象,Assembly.FullName然后检查AssemblyName.KeyPair属性的公钥,它必须与您的公钥令牌匹配(只需比较)与GetExecutingAssembly()).
  • 如果并非所有程序集都已签名,则可以执行相同的操作,但过滤掉与系统程序集的公钥标记匹配的所有程序集(这可能是最简单的情况,也包括第3部分库).

请注意,并非所有系统程序集都具有相同的公钥令牌(即使在相同的Framework版本中),因此您必须收集并检查键列表(只需浏览c:\windows\assembly以阅读它们).一个好方法可能是检查公钥,然后使用第二个过滤器AssemblyCompanyAttribute.


Law*_*ard 6

如果部署'*.pdb'文件并且只是尝试从异常中获取堆栈跟踪,则可以获取异常的StackTrace属性并将其拆分为行并过滤掉没有源代码引用的行.

        catch (Exception ex)
        {
            var lines = ex.StackTrace
                .Split(new[] {Environment.NewLine}, StringSplitOptions.None)
                .Where(l => Regex.IsMatch(l, @"([^\)]*\)) in (.*):line (\d)*$"));
            var userStackTrace = string.Join(Environment.NewLine, lines);
        }
Run Code Online (Sandbox Code Playgroud)