我正在尝试调查崩溃转储中的错误(因此我无法更改代码)。我有一个非常复杂的对象(序列化表示中有数千行),它的状态是不一致的。要调查其状态,Visual Studio 调试器视图是无用的。但是该对象具有数据合同。我想序列化它,然后使用我最喜欢的文本编辑器在对象中导航。是否可以从调试器中执行?
11 回答
运气好的话,你的 appdomain 中已经有了 Json.Net。在这种情况下,将其弹出到您的即时窗口中:
Newtonsoft.Json.JsonConvert.SerializeObject(someVariable)
前段时间我写了这个单行序列化对象到磁盘上的文件。将其复制/粘贴到您的即时窗口,并obj
用您的对象替换(它被引用两次)。它会将text.xml
文件保存到c:\temp
,根据自己的喜好进行更改。
(new System.Xml.Serialization.XmlSerializer(obj.GetType())).Serialize(new System.IO.StreamWriter(@"c:\temp\text.xml"), obj)
但是不要指望任何魔法,如果对象不能被序列化,它会抛出异常。
这是一个 Visual Studio 扩展,它可以让你做到这一点:
https://visualstudiogallery.msdn.microsoft.com/c6a21c68-f815-4895-999f-cd0885d8774f
您可以输出到 JSON、XML 或 C#
由于.NET Core 3.0
您可以使用System.Text.Json
:
System.Text.Json.JsonSerializer.Serialize(obj)
在 Visual Studio 的“立即”窗口中使用它,替换c:\directory\file.json
为您要写入 JSON 的文件的完整路径以及myObject
要序列化的变量:
System.IO.File.WriteAllText(@"c:\directory\file.json", Newtonsoft.Json.JsonConvert.SerializeObject(myObject))
我有一个我使用的扩展方法:
public static void ToSerializedObjectForDebugging(this object o, FileInfo saveTo)
{
Type t = o.GetType();
XmlSerializer s = new XmlSerializer(t);
using (FileStream fs = saveTo.Create())
{
s.Serialize(fs, o);
}
}
我用 saveTo 的字符串重载它并从即时窗口调用它:
public static void ToSerializedObjectForDebugging(this object o, string saveTo)
{
ToSerializedObjectForDebugging(o, new FileInfo(saveTo));
}
可以使用即时窗口对其进行序列化,然后将内容复制到您喜欢的编辑器中。
另一种选择是覆盖该ToString()
方法并在调试模式下调用它。
您还可以在崩溃前不久将内容写入文件,或者将代码包装到 try/catch 中然后写入文件。我假设您可以识别它何时崩溃。
我一直在使用ObjectDumper.Net。
它运行良好,尤其是在您进行实时单元测试的情况下。当测试运行时,我可以轻松地在控制台中查看变量的值,从而使我免于手动调试。
如果您使用的是 XUnit,这可能会有所帮助。
Omar Elabd 答案的一个变体——
它不是免费的,但有 OzCode 的免费试用版
( https://marketplace.visualstudio.com/items?itemName=CodeValueLtd.OzCode )。
那里的上下文/悬停菜单中有内置的 JSON 导出功能,它比 Object Export 扩展更好(权衡它不是免费的)。
http://o.oz-code.com/features#export(演示)
我知道这是事实发生几年后的事,但我在这里留下一个答案,因为这对我有用,其他人可能会觉得它有用。
如果您有循环引用,请在直接窗口中运行:
Newtonsoft.Json.JsonConvert.SerializeObject(app, Newtonsoft.Json.Formatting.Indented,
new Newtonsoft.Json.JsonSerializerSettings
{
ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize
});
阿列克谢答案的变体。稍微复杂一些,但不涉及写入文本文件:
1) 在即时窗口中输入:
System.IO.StringWriter stringWriter = new System.IO.StringWriter();
2) 在 Watch Window 中输入两个手表:
a. stringWriter
b. new System.Xml.Serialization.XmlSerializer(obj.GetType()).Serialize(stringWriter, obj)
进入第二个监视(序列化)后,stringWriter 监视值将设置为 obj 序列化为 XML。复制并粘贴它。请注意,XML 将包含在花括号 {...} 中,因此如果您想将 XML 用于任何内容,则需要删除它们。