Visual Studio come serializzare un oggetto dal debugger


90

Sto cercando di indagare su un bug in un crash dump (quindi non posso modificare il codice). Ho un oggetto davvero complicato (migliaia di righe nella rappresentazione serializzata) e il suo stato è incoerente. Per indagare sul suo stato, la visualizzazione del debugger di Visual Studio è inutile. Ma l'oggetto ha un contratto dati. Vorrei serializzarlo e quindi utilizzare il mio editor di testo preferito per navigare nell'oggetto. È possibile eseguire l'operazione dal debugger?


Si noti che se si dispone di una classe contenitore personalizzata o di un'altra classe ciò che si desidera vedere molte volte durante il debug, ma IntelliSense e QuickView non riescono a capirlo, è possibile scrivere un'estensione per VS che aiuta a mostrare la propria classe personalizzata in debug.
Csaba Toth

Si possono trovare anche molte buone tecniche [qui] ( stackoverflow.com/questions/360277/… )
Josh

Risposte:


89

Qualche tempo fa ho scritto questo one-liner serializzando un oggetto in un file sul disco. Copia / incolla nella finestra Immediata e sostituisci obj(è referenziato due volte) con il tuo oggetto. Salverà un text.xmlfile in c:\temp, lo cambierà a tuo piacimento.

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

Non aspettarti alcuna magia, se l'oggetto non può essere serializzato, genererà un'eccezione.


3
Questo ha funzionato per me nella finestra immediata. voto positivo,
Pankaj Kumar

1
quando lo uso nella finestra immediata di VS 2015, ottengo questo "errore": "La valutazione dei metodi nativi in ​​questo contesto non è supportata." Idee?
Vetras

Quando lo eseguo, ricevo il seguente messaggio:identifier "System" is undefined
Rasoul

Avevo un vecchio progetto VB.NET, dovevo metterlo in questo modo altrimenti ricevevo un errore sulla sintassi dell'espressione, se qualcuno necessitava: new System.Xml.Serialization.XmlSerializer (obj.GetType ()). Serialize (New System.IO .StreamWriter ("C: \ temp \ temp.txt"), obj)
Liquid Core

Questo è spettacolare. Ho dovuto usare una directory diversa a causa dei permessi di scrittura, ma ha funzionato a meraviglia. Importa in Excel ed è persino carino.
BuddyZ

164

Con un po 'di fortuna hai già Json.Net nel tuo dominio app. In tal caso, inseriscilo nella finestra Immediata:

Newtonsoft.Json.JsonConvert.SerializeObject(someVariable)


20
Vorrei poter votare di nuovo, soprattutto rispetto alle altre risposte. (Scusa, ma non ho bisogno di vedere un'altra riga di XML nella mia carriera.)
yzorg

1
Dopo una sessione di debug di test molto lunga, si è verificata un'eccezione nel mio programma prima che potesse scrivere migliaia di risultati del test in un file, ero su un punto di interruzione in cui si è verificata l'eccezione e potevo ancora ispezionare la raccolta dei risultati. Questo suggerimento mi ha fatto risparmiare molto tempo!
HAL9000

1
Potrebbe essere necessario utilizzare effettivamente Json.Net anche da qualche altra parte in modo che venga caricato quando si tenta di utilizzarlo nella finestra Immediata (invece di aggiungere semplicemente il riferimento).
Evan

1
Ho dovuto aggiungere il pacchetto Newtonsoft.Json usando Nuget e anche una riga di codice nel metodo in cui avevo il punto di interruzione per creare una classe fittizia Newtonsoft.Json.JsonArrayAttribute () per farlo funzionare. Una soluzione eccellente!
Richard Moore

1
Questa è un'ottima risposta. Lo uso con solo una piccola modifica per risparmiarmi un viaggio all'abbellitore. Newtonsoft.Json.JsonConvert.SerializeObject (someVariable, Newtonsoft.Json.Formatting.Indented)
Jamie

37

Ecco un'estensione di Visual Studio che ti consentirà di fare esattamente questo:

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

È possibile eseguire l'output in JSON, XML o C #


4
Quel collegamento sembra essere interrotto, ma qui c'è il progetto github e puoi trovarlo se cerchi "Object Exporter" nella finestra di dialogo "Estensioni e aggiornamenti ..." in Visual Studio. Grande estensione btw!
Niklas Söderberg

2
Grazie @Omar L'idea è perfetta. Ma ci vuole troppo tempo e in alcuni casi si blocca
Wahid Bitar

1
Concordato con @WahidBitar - Ottimo concetto - perfetto per impostare i dati di unit test, ma l'estensione sembra piuttosto difettosa e porta con sé Visual Studio quando si blocca!
Dib

Questo è davvero uno strumento molto utile.
Ashutosh Singh


4

Usalo nella finestra "Immediate" di Visual Studio, sostituendo c:\directory\file.jsoncon il percorso completo del file in cui desideri scrivere il JSON e myObjectcon la tua variabile da serializzare:

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

3

Ho un metodo di estensione che utilizzo:

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

Lo sovraccarico con una stringa per saveTo e lo chiamo dalla finestra immediata:

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

3

Potrebbe essere possibile utilizzare la finestra immediata per serializzarlo e quindi copiare il contenuto nel tuo editor preferito.

Un'altra opzione è sovrascrivere il ToString()metodo e chiamarlo mentre si è in modalità di debug.

Puoi anche scrivere il contenuto su un file poco prima del crash, o racchiudere il codice in un try / catch e poi scrivere il file. Suppongo che tu possa identificare quando si blocca.


Grazie, ho provato lo stesso dalla finestra di controllo, ma mi ha detto "La valutazione della funzione richiede l'esecuzione di tutti i thread". Finestra immediata risolverlo
xvorsx

1

Una variazione sulla risposta di Omar Elabd -

Non è gratuito, ma è disponibile una prova gratuita per OzCode
( https://marketplace.visualstudio.com/items?itemName=CodeValueLtd.OzCode ).

C'è l'esportazione integrata in JSON all'interno del menu contestuale / hover lì, e funziona un po 'meglio dell'estensione Object Export (il compromesso per non essere gratuito).

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

So che sono passati alcuni anni dal fatto, ma lascio una risposta qui perché ha funzionato per me e qualcun altro potrebbe trovarlo utile.


1

Se hai un riferimento circolare, eseguilo nella finestra immediata:

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

1

Sto usando ObjectDumper.Net .

Funziona bene, soprattutto se si dispone di test di unità dal vivo. Posso facilmente visualizzare il valore di una variabile nella console quando viene eseguito un test, salvandomi dal debug manuale.

Questo può aiutare se stai usando XUnit.


0

Una variazione sulla risposta di Alexey. Leggermente più complicato ma non comporta la scrittura su un file di testo:

1) Nella finestra immediata inserire:

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

2) Nella finestra di controllo inserisci due orologi:

a.  stringWriter

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

Dopo aver inserito il secondo watch (quello Serialize), il valore del watch di stringWriter verrà impostato su obj serializzato in XML. Copia e incolla. Nota che l'XML sarà racchiuso tra parentesi graffe, {...}, quindi dovrai rimuoverli se vuoi usare l'XML per qualsiasi cosa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.