我正在尝试实现更复杂的错误处理.为了实现我的目标,我需要从curent StackTrace中过滤掉非用户代码方法(框架).
在ASP.NET典型的StackTrace中,您可能会猜到许多方法与调试目的无关,因为它们不在用户代码中.Visual Studio为您提供了筛选出这个非用户代码(框架)的选项,因此我猜它是可能的.然而,在探索StackFrames(以及方法,模块,程序集......)的方法和属性大约30分钟后,我找不到任何可用于识别"系统"框架的东西.
我最终手动指定了我要记录的模块(模块是程序集的一部分,在我的例子中是1:1).
有没有更好的方法来做到这一点?只需包含核心ASP.NET之外的所有内容
StackFrameclass具有GetMethod()成员函数,来自检索MethodBase对象.
如果您只需要一个天真的过滤器,您可以执行以下操作之一:
AssemblyCompanyAttribute并过滤"Microsoft Corporation"生成的程序集.这比以前的方法更好,因为有时候我看到了将自己的类型放在System命名空间中的库.如果您需要更多内容,可以获取MethodBase.Module定义该方法的module().现在您有两个选择:
Module.Assembly属性定义模块的程序集,构建AssemblyName对象,Assembly.FullName然后检查AssemblyName.KeyPair属性的公钥,它必须与您的公钥令牌匹配(只需比较)与GetExecutingAssembly()).请注意,并非所有系统程序集都具有相同的公钥令牌(即使在相同的Framework版本中),因此您必须收集并检查键列表(只需浏览c:\windows\assembly以阅读它们).一个好方法可能是检查公钥,然后使用第二个过滤器AssemblyCompanyAttribute.
如果部署'*.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)