Visual Studio zum Serialisieren von Objekten aus dem Debugger

86

Ich versuche, einen Fehler in einem Absturzspeicherauszug zu untersuchen (daher kann ich den Code nicht ändern). Ich habe ein wirklich kompliziertes Objekt (Tausende von Zeilen in der serialisierten Darstellung) und sein Zustand ist inkonsistent. Um den Status zu untersuchen, ist die Visual Studio-Debugger-Ansicht unbrauchbar. Das Objekt hat jedoch einen Datenvertrag. Ich möchte es serialisieren und dann mit meinem bevorzugten Texteditor über das Objekt navigieren. Ist es möglich, das vom Debugger aus zu tun?

xvorsx
quelle
Beachten Sie, dass Sie eine Erweiterung für VS schreiben können, wenn Sie über eine benutzerdefinierte Containerklasse oder eine andere Klasse verfügen, die Sie während des Debuggens häufig sehen möchten, IntelliSense und QuickView dies jedoch nicht herausfinden können debuggen.
Csaba Toth
Viele gute Techniken finden Sie auch [hier] ( stackoverflow.com/questions/360277/… )
Josh

Antworten:

82

Vor einiger Zeit habe ich diesen Einzeiler geschrieben, der ein Objekt in eine Datei auf der Festplatte serialisiert. Kopieren Sie es in Ihr Direktfenster und ersetzen Sie objes durch Ihr Objekt (es wird zweimal referenziert). Es wird eine text.xmlDatei gespeichert c:\temp, um sie nach Ihren Wünschen zu ändern.

(new System.Xml.Serialization.XmlSerializer(obj.GetType())).Serialize(new System.IO.StreamWriter(@"c:\temp\text.xml"), obj)

Erwarten Sie jedoch keine Magie. Wenn das Objekt nicht serialisiert werden kann, wird eine Ausnahme ausgelöst.

Alexey
quelle
2
Das hat bei mir im unmittelbaren Fenster geklappt. upvoted,
Pankaj Kumar
1
Wenn ich dies im VS 2015-Sofortfenster verwende, wird der folgende Fehler angezeigt: "Die Auswertung nativer Methoden in diesem Kontext wird nicht unterstützt." Ideen?
Vetras
Wenn ich es starte, erhalte ich die folgende Nachricht:identifier "System" is undefined
Rasoul
Hatte ein altes VB.NET-Projekt, musste es so ausdrücken, sonst bekam ich einen Fehler bezüglich der Ausdruckssyntax, wenn jemand benötigt: new System.Xml.Serialization.XmlSerializer (obj.GetType ()). Serialize (New System.IO .StreamWriter ("C: \ temp \ temp.txt"), obj)
Liquid Core
Das ist spektakulär. Ich musste aufgrund von Schreibberechtigungen ein anderes Verzeichnis verwenden, aber es funktionierte wie ein Zauber. In Excel importieren und es ist sogar hübsch.
BuddyZ
152

Mit etwas Glück haben Sie Json.Net bereits in Ihrer Appdomain. In diesem Fall fügen Sie dies in Ihr Sofortfenster ein:

Newtonsoft.Json.JsonConvert.SerializeObject(someVariable)

mcintyre321
quelle
18
Ich wünschte, ich könnte dies wieder positiv bewerten, insbesondere im Vergleich zu den anderen Antworten. (Entschuldigung, aber ich muss in meiner Karriere keine weitere XML-Zeile sehen.)
Yzorg
1
Nach einer sehr langen Test-Debug-Sitzung ist in meinem Programm eine Ausnahme aufgetreten, bevor Tausende von Testergebnissen in eine Datei geschrieben werden konnten. Ich befand mich an einem Haltepunkt, an dem die Ausnahme auftrat, und konnte die Ergebnissammlung weiterhin überprüfen. Dieser Tipp hat mir viel Zeit gespart!
HAL9000
1
Möglicherweise müssen Sie Json.Net auch an einer anderen Stelle verwenden, damit es geladen wird, wenn Sie versuchen, es im Direktfenster zu verwenden (anstatt nur die Referenz hinzuzufügen).
Evan
1
Ich musste das Newtonsoft.Json-Paket mit Nuget hinzufügen und der Methode, in der ich den Haltepunkt hatte, eine Codezeile hinzufügen, um eine Dummy-Newtonsoft.Json.JsonArrayAttribute () -Klasse zu erstellen, damit es funktioniert. Eine hervorragende Lösung!
Richard Moore
Und wenn Sie es nicht haben, können Sie es über das unmittelbare Fenster laden. Weitere Informationen finden Sie unter stackoverflow.com/a/29834931
yoel halb
36

Hier ist eine Visual Studio-Erweiterung, mit der Sie genau das tun können:

https://visualstudiogallery.msdn.microsoft.com/c6a21c68-f815-4895-999f-cd0885d8774f

Sie können in JSON, XML oder C # ausgeben

Omar Elabd
quelle
4
Dieser Link scheint defekt zu sein, aber hier ist das Github-Projekt, das Sie finden können, wenn Sie im Dialogfeld "Erweiterungen und Updates ..." in Visual Studio nach "Object Exporter" suchen. Tolle Erweiterung übrigens!
Niklas Söderberg
2
Danke @Omar Die Idee ist perfekt. Aber es dauert zu lange und in einigen Fällen einfrieren
Wahid Bitar
1
Einverstanden mit @WahidBitar - Tolles Konzept - perfekt zum Einrichten von Unit-Testdaten, aber die Erweiterung scheint ziemlich fehlerhaft zu sein und nimmt Visual Studio mit, wenn sie abstürzt!
Dib
Dies ist wirklich ein sehr nützliches Werkzeug.
Ashutosh Singh
4

Verwenden Sie diese Option im Fenster "Sofort" von Visual Studio und ersetzen Sie sie c:\directory\file.jsondurch den vollständigen Pfad zu der Datei, in die Sie den JSON schreiben möchten, und myObjectdurch Ihre zu serialisierende Variable:

System.IO.File.WriteAllText(@"c:\directory\file.json", Newtonsoft.Json.JsonConvert.SerializeObject(myObject))
Chris Peacock
quelle
3

Ich habe eine Erweiterungsmethode, die ich verwende:

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);
    }
}

Ich überlade es mit einer Zeichenfolge für saveTo und rufe es aus dem unmittelbaren Fenster auf:

public static void ToSerializedObjectForDebugging(this object o, string saveTo)
{
    ToSerializedObjectForDebugging(o, new FileInfo(saveTo));
}
Mike Cheel
quelle
3

Möglicherweise können Sie das unmittelbare Fenster verwenden, um es zu serialisieren und den Inhalt dann in Ihren bevorzugten Editor zu kopieren.

Eine andere Möglichkeit besteht darin, die ToString()Methode zu überschreiben und im Debug-Modus aufzurufen.

Sie können den Inhalt auch kurz vor dem Absturz in eine Datei schreiben oder den Code in einen Versuch / Fang einwickeln und die Datei dann schreiben. Ich gehe davon aus, dass Sie erkennen können, wann es abstürzt.

Chuck Conway
quelle
Vielen Dank, ich habe dasselbe im Überwachungsfenster versucht, aber es sagte mir: "Für die Funktionsbewertung müssen alle Threads ausgeführt werden." Sofortiges Fenster lösen es
xvorsx
1

Eine Variation der Antwort von Omar Elabd -

Es ist nicht kostenlos, aber es gibt eine kostenlose Testversion für OzCode
( https://marketplace.visualstudio.com/items?itemName=CodeValueLtd.OzCode ).

Es gibt einen integrierten Export nach JSON im Kontext- / Hover-Menü, und es funktioniert etwas besser als die Objektexporterweiterung (der Kompromiss, dass es nicht kostenlos ist).

http://o.oz-code.com/features#export (Demo)

Ich weiß, dass dies einige Jahre später ist, aber ich hinterlasse hier eine Antwort, weil dies für mich funktioniert hat und jemand anderes es möglicherweise nützlich findet.

Michael Armes
quelle
1

Wenn Sie einen Zirkelverweis haben, führen Sie diesen im unmittelbaren Fenster aus:

Newtonsoft.Json.JsonConvert.SerializeObject(app, Newtonsoft.Json.Formatting.Indented,
new Newtonsoft.Json.JsonSerializerSettings
{
    ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize
});
InGeek
quelle
1

Ich habe ObjectDumper.Net verwendet .

Es funktioniert gut, besonders wenn Sie Live-Unit-Tests haben. Ich kann den Wert einer Variablen einfach in der Konsole anzeigen, wenn ein Test ausgeführt wird, sodass ich nicht manuell debuggen muss.

Dies kann hilfreich sein, wenn Sie XUnit verwenden.

DharmaTurtle
quelle
0

Eine Variation von Alexeys Antwort. Etwas komplizierter, aber ohne Schreiben in eine Textdatei:

1) Geben Sie im Direktfenster Folgendes ein:

System.IO.StringWriter stringWriter = new System.IO.StringWriter();  

2) Geben Sie im Überwachungsfenster zwei Uhren ein:

a.  stringWriter

b.  new System.Xml.Serialization.XmlSerializer(obj.GetType()).Serialize(stringWriter, obj) 

Nachdem Sie die zweite Watch (die Serialize) eingegeben haben, wird der StringWriter-Watch-Wert auf obj serialisiert in XML gesetzt. Kopieren Sie es und fügen Sie es ein. Beachten Sie, dass das XML in geschweiften Klammern {...} eingeschlossen wird. Sie müssen sie daher entfernen, wenn Sie das XML für irgendetwas verwenden möchten.

Simon Tewsi
quelle