使用Exception.Data

你如何在你曾经使用过的C#项目中使用Exception.Data属性?

我想要提供一个模式的答案,而不是那些非常特定于您的应用程序的答案。

我使用的exceptionlogging器已经调整了写出数据集合中的所有项目。 然后,对于我们遇到的exception堆栈中无法诊断的每个exception,我们都会添加该函数范围内的所有数据,发送一个新的构build,并等待它重新发生。

我想我们是乐观主义者,因为我们没有把它放在每一个function上,但是我们是悲观主义者,因为一旦我们解决了这个问题,我们就不会把它拿出来。

当我知道我正在创build的exception需要被序列化时,我已经使用了它。 有一天使用Reflector,我发现Excepion.Data被卡在串行化stream中。

所以,基本上,如果我的自定义exception类的属性已经是可序列化types,那么我将它们实现在派生类上,并使用基础数据对象作为其存储机制,而不是创build私有字段来保存数据。 如果我的自定义exception对象的属性需要更高级的序列化,我通常使用支持私有字段并在派生类中处理它们的序列化来实现它们。

底线,Exception.Data给你免费的序列化只是通过坚持你的属性 – 但只记得这些项目需要序列化!

我使用它来捕获有关exception时从封闭范围的状态信息,因为exception向上移动堆栈。 像导致exception的文件名或某些ID的值将有助于跟踪问题的项目。

在Web应用程序的最顶层,我也倾向于添加许多请求信息,如RawUrl,Cookie,Referrer,…

有关更多详细信息,请参阅以下主题的博客 :

与其等待问题发生,我将这些代码添加到与外部事件(例如文件名或被访问的URL)相关的exception的地方,换句话说,任何有助于重新生成问题。

由于没有答案包含任何代码。 一些可能有用的作为这个问题的补充是如何真正看看。数字字典。 由于它不是通用字典,只能返回IDictionary

foreach(var kvp in exception.Data)的types实际上是无用的object 。 但是从MSDN有一个简单的方法来迭代这个字典:

 foreach (DictionaryEntry de in e.Data) Console.WriteLine(" Key: {0,-20} Value: {1}", "'" + de.Key.ToString() + "'", de.Value); 

我真的不知道格式参数是什么意思, , -20可能意味着可能采取(20)? Digressing …这个代码可以在一个普通的错误logging器中放松这些数据。 更完整的用法类似于:

 var messageBuilder = new StringBuilder(); do { foreach (DictionaryEntry kvp in exception.Data) messageBuilder.AppendFormat("{0} : {1}\n", kvp.Key, kvp.Value); messageBuilder.AppendLine(exception.Message); } while ((exception = exception.InnerException) != null); return messageBuilder.ToString();