Visual Studio comment sérialiser un objet à partir du débogueur

88

J'essaye d'enquêter sur un bogue dans un vidage sur incident (donc je ne peux pas changer le code). J'ai un objet vraiment compliqué (des milliers de lignes dans la représentation sérialisée) et son état est incohérent. Pour étudier son état, la vue du débogueur Visual Studio est inutile. Mais l'objet a un contrat de données. Je voudrais le sérialiser, puis utiliser mon éditeur de texte préféré pour naviguer à travers l'objet. Est-il possible de faire le depuis le débogueur?

xvorsx
la source
Notez que si vous avez une classe de conteneur personnalisée ou une autre classe que vous voulez voir plusieurs fois pendant le débogage, mais que IntelliSense et QuickView ne peuvent pas le comprendre, vous pouvez écrire une extension pour VS qui aide à afficher votre classe personnalisée dans déboguer.
Csaba Toth
De nombreuses bonnes techniques peuvent également être trouvées [ici] ( stackoverflow.com/questions/360277/… )
Josh

Réponses:

86

Il y a quelque temps, j'ai écrit ce one-liner sérialisant un objet dans un fichier sur le disque. Copiez / collez-le dans votre fenêtre Exécution et remplacez-le obj(il est référencé deux fois) par votre objet. Il enregistrera un text.xmlfichier c:\tempet le modifiera à votre guise.

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

Ne vous attendez pas à de la magie, si l'objet ne peut pas être sérialisé, il lèvera une exception.

Alexey
la source
3
Cela a fonctionné pour moi dans la fenêtre immédiate. upvoted,
Pankaj Kumar
1
lorsque j'utilise ceci sur la fenêtre immédiate de VS 2015, j'obtiens cette 'erreur': «L'évaluation des méthodes natives dans ce contexte n'est pas prise en charge. Des idées?
Vetras
Quand je le lance, je reçois le message suivant:identifier "System" is undefined
Rasoul
J'avais un ancien projet VB.NET, je devais le mettre comme ça, sinon j'obtenais une erreur sur la syntaxe de l'expression, si quelqu'un avait besoin de: nouveau System.Xml.Serialization.XmlSerializer (obj.GetType ()). Serialize (New System.IO .StreamWriter ("C: \ temp \ temp.txt"), obj)
Liquid Core
C'est spectaculaire. J'ai dû utiliser un répertoire différent en raison des autorisations d'écriture, mais cela a fonctionné comme un charme. Importez dans Excel et c'est même joli.
BuddyZ
160

Avec un peu de chance, vous avez déjà Json.Net dans votre domaine d'application. Dans ce cas, insérez ceci dans votre fenêtre Exécution:

Newtonsoft.Json.JsonConvert.SerializeObject(someVariable)

mcintyre321
la source
19
J'aimerais pouvoir à nouveau voter pour cela, surtout par rapport aux autres réponses. (Désolé, mais je n'ai pas besoin de voir une autre ligne de XML dans ma carrière.)
yzorg
1
Après une très longue session de débogage de test, une exception s'est produite dans mon programme avant qu'il ne puisse écrire des milliers de résultats de test dans un fichier, j'étais sur un point d'arrêt où l'exception s'est produite et je pouvais toujours inspecter la collection de résultats. Cette astuce m'a fait gagner beaucoup de temps!
HAL9000
1
Vous devrez peut-être utiliser Json.Net ailleurs afin qu'il soit chargé lorsque vous essayez de l'utiliser dans la fenêtre Exécution (au lieu d'ajouter simplement la référence).
Evan
1
J'ai dû ajouter le package Newtonsoft.Json en utilisant Nuget, et également ajouter une ligne de code dans la méthode dans laquelle j'avais le point d'arrêt pour créer une classe factice Newtonsoft.Json.JsonArrayAttribute () pour le faire fonctionner. Une excellente solution!
Richard Moore
1
C'est une excellente réponse. Je l'utilise avec juste un petit changement pour me sauver un voyage à l'embellisseur. Newtonsoft.Json.JsonConvert.SerializeObject (someVariable, Newtonsoft.Json.Formatting.Indented)
Jamie
37

Voici une extension Visual Studio qui vous permettra de faire exactement cela:

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

Vous pouvez exporter vers JSON, XML ou C #

Omar Elabd
la source
4
Ce lien semble rompu, mais voici le projet github et vous pouvez le trouver si vous recherchez «Object Exporter» dans la boîte de dialogue «Extensions and Updates ...» de Visual Studio. Grande extension btw!
Niklas Söderberg
2
Merci @Omar L'idée est parfaite. Mais cela prend trop de temps et se fige dans certains cas
Wahid Bitar
1
D'accord avec @WahidBitar - Excellent concept - parfait pour configurer des données de test unitaire, mais l'extension semble assez boguée et emporte Visual Studio avec elle quand il plante!
Dib
C'est vraiment un outil très utile.
Ashutosh Singh
4

Utilisez ceci dans la fenêtre "Immédiat" de Visual Studio, en remplaçant c:\directory\file.jsonpar le chemin d'accès complet au fichier dans lequel vous souhaitez écrire le JSON et myObjectpar votre variable à sérialiser:

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

J'ai une méthode d'extension que j'utilise:

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

Je le surcharge avec une chaîne pour saveTo et l'appelle depuis la fenêtre immédiate:

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

Il peut être possible d'utiliser la fenêtre immédiate pour la sérialiser, puis copier le contenu dans votre éditeur préféré.

Une autre option consiste à remplacer la ToString()méthode et à l'appeler en mode débogage.

Vous pouvez également écrire le contenu dans un fichier peu de temps avant le crash, ou encapsuler le code dans un try / catch et écrire le fichier ensuite. Je suppose que vous pouvez identifier quand il plante.

Chuck Conway
la source
Merci, j'ai essayé la même chose depuis la fenêtre de surveillance, mais il m'a dit "L'évaluation de la fonction nécessite que tous les threads s'exécutent." Fenêtre immédiate résolvez-le
xvorsx
1

Une variation sur la réponse d'Omar Elabd -

Ce n'est pas gratuit, mais il existe un essai gratuit pour OzCode
( https://marketplace.visualstudio.com/items?itemName=CodeValueLtd.OzCode ).

Il y a une exportation intégrée vers JSON dans le menu contextuel / survolé, et cela fonctionne un peu mieux que l'extension Object Export (le compromis pour ce n'est pas gratuit).

http://o.oz-code.com/features#export (démo)

Je sais que c'est quelques années après les faits, mais je laisse une réponse ici parce que cela a fonctionné pour moi, et quelqu'un d'autre peut la trouver utile.

Michael Armes
la source
1

Si vous avez une référence circulaire, exécutez-la dans la fenêtre immédiate:

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

J'utilise ObjectDumper.Net .

Cela fonctionne bien, surtout si vous avez des tests unitaires en direct. Je peux facilement afficher la valeur d'une variable dans la console lorsqu'un test s'exécute, ce qui m'évite de déboguer manuellement.

Cela peut aider si vous utilisez XUnit.

DharmaTurtle
la source
0

Une variation de la réponse d'Alexey. Légèrement plus compliqué mais n'implique pas d'écrire dans un fichier texte:

1) Dans la fenêtre immédiate, entrez:

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

2) Dans la fenêtre de surveillance, entrez deux montres:

a.  stringWriter

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

Une fois que vous avez entré la deuxième montre (celle de Sérialisation), la valeur de la surveillance stringWriter sera définie sur obj sérialisé en XML. Copiez et collez-le. Notez que le XML sera entre accolades, {...}, vous devrez donc les supprimer si vous voulez utiliser le XML pour quoi que ce soit.

Simon Tewsi
la source