Visual Studio cómo serializar un objeto desde el depurador

88

Estoy tratando de investigar un error en un volcado de memoria (por lo que no puedo cambiar el código). Tengo un objeto realmente complicado (miles de líneas en la representación serializada) y su estado es inconsistente. Para investigar su estado, la vista del depurador de Visual Studio es inútil. Pero el objeto tiene un contrato de datos. Me gustaría serializarlo y luego usar mi editor de texto favorito para navegar por el objeto. ¿Es posible hacer el depurador?

xvorsx
fuente
Tenga en cuenta que si tiene alguna clase de contenedor personalizada, o alguna otra clase que desea ver muchas veces durante la depuración, pero IntelliSense y QuickView no pueden resolverlo, puede escribir una extensión para VS que ayude a mostrar su clase personalizada en depurar.
Csaba Toth
También se pueden encontrar muchas buenas técnicas [aquí] ( stackoverflow.com/questions/360277/… )
Josh

Respuestas:

86

Hace algún tiempo escribí este resumen serializando un objeto en un archivo en el disco. Cópielo / péguelo en su ventana Inmediato y reemplácelo obj(se hace referencia dos veces) con su objeto. Guardará un text.xmlarchivo en c:\temp, cámbielo a su gusto.

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

Sin embargo, no espere magia, si el objeto no se puede serializar, generará una excepción.

Alexey
fuente
3
Esto funcionó para mí en la ventana inmediata. voto a favor,
Pankaj Kumar
1
cuando uso esto en la ventana inmediata de VS 2015, aparece este 'error': "No se admite la evaluación de métodos nativos en este contexto". Ideas?
Vetras
Cuando lo ejecuto, aparece el siguiente mensaje:identifier "System" is undefined
Rasoul
Tenía un proyecto VB.NET antiguo, tenía que ponerlo así, de lo contrario, recibía un error sobre la sintaxis de la expresión, si alguien necesita: new System.Xml.Serialization.XmlSerializer (obj.GetType ()). Serialize (New System.IO .StreamWriter ("C: \ temp \ temp.txt"), obj)
Liquid Core
Esto es espectacular. Tuve que usar un directorio diferente debido a los permisos de escritura, pero funcionó a la perfección. Importa a Excel y es incluso bonito.
BuddyZ
160

Con suerte, ya tienes Json.Net en tu dominio de aplicación. En cuyo caso, introduzca esto en su ventana Inmediato:

Newtonsoft.Json.JsonConvert.SerializeObject(someVariable)

mcintyre321
fuente
19
Ojalá pudiera votar esto nuevamente, especialmente en comparación con las otras respuestas. (Lo siento, pero no necesito ver otra línea de XML en mi carrera.)
yzorg
1
Después de una sesión de depuración de prueba muy larga, ocurrió una excepción en mi programa antes de que pudiera escribir miles de resultados de prueba en un archivo, estaba en un punto de interrupción donde ocurrió la excepción y aún podía inspeccionar la colección de resultados. ¡Este consejo me ahorró mucho tiempo!
HAL9000
1
Es posible que también deba usar Json.Net en otro lugar para que se cargue cuando intente usarlo en la ventana Inmediato (en lugar de simplemente agregar la referencia).
Evan
1
Tuve que agregar el paquete Newtonsoft.Json usando Nuget, y también agregar una línea de código en el método en el que tenía el punto de interrupción para crear una clase Newtonsoft.Json.JsonArrayAttribute () ficticia para que funcione. ¡Una excelente solución!
Richard Moore
1
Esta es una respuesta genial. Lo uso con solo un pequeño cambio para ahorrarme un viaje al embellecedor. Newtonsoft.Json.JsonConvert.SerializeObject (someVariable, Newtonsoft.Json.Formatting.Indented)
Jamie
37

Aquí hay una extensión de Visual Studio que le permitirá hacer exactamente eso:

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

Puede generar en JSON, XML o C #

Omar Elabd
fuente
4
Ese enlace parece estar roto, pero aquí está el proyecto github y puede encontrarlo si busca "Exportador de objetos" en el cuadro de diálogo "Extensiones y actualizaciones ..." en Visual Studio. ¡Gran extensión por cierto!
Niklas Söderberg
2
Gracias @Omar La idea es perfecta. Pero lleva demasiado tiempo y se congela en algunos casos
Wahid Bitar
1
De acuerdo con @WahidBitar - Gran concepto - perfecto para configurar datos de prueba unitaria, pero la extensión parece bastante defectuosa, ¡y lleva Visual Studio consigo cuando falla!
Dib
Esta es realmente una herramienta muy útil.
Ashutosh Singh
4

Use esto en la ventana "Inmediato" de Visual Studio, reemplazando c:\directory\file.jsoncon la ruta completa al archivo en el que le gustaría escribir el JSON y myObjectcon su variable para serializar:

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

Tengo un método de extensión que uso:

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 sobrecargo con una cadena para saveTo y lo llamo desde la ventana inmediata:

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

Podría ser posible usar la ventana inmediata para serializarlo y luego copiar el contenido a su editor favorito.

Otra opción es anular el ToString()método y llamarlo mientras está en modo de depuración.

También puede escribir el contenido en un archivo poco antes del bloqueo, o envolver el código en un try / catch y luego escribir el archivo. Supongo que puede identificar cuándo se bloquea.

Chuck Conway
fuente
Gracias, intenté lo mismo desde la ventana Watch, pero me dijo "La evaluación de la función requiere que se ejecuten todos los subprocesos". Ventana inmediata resolverlo
xvorsx
1

Una variación de la respuesta de Omar Elabd:

No es gratis, pero hay una prueba gratuita de OzCode
( https://marketplace.visualstudio.com/items?itemName=CodeValueLtd.OzCode ).

Hay una exportación incorporada a JSON dentro del menú contextual / flotante allí, y funciona un poco mejor que la extensión Object Export (la compensación por no ser gratuita).

http://o.oz-code.com/features#export (demostración)

Sé que esto es unos años después del hecho, pero dejo una respuesta aquí porque esto funcionó para mí, y alguien más puede encontrarlo útil.

Michael Armes
fuente
1

En caso de que tenga una referencia circular, ejecute esto en la ventana inmediata:

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

He estado usando ObjectDumper.Net .

Funciona bien, especialmente si tiene pruebas de unidades en vivo. Puedo ver fácilmente el valor de una variable en la consola cuando se ejecuta una prueba, lo que me ahorra tener que depurar manualmente.

Esto puede ayudar si está usando XUnit.

DharmaTurtle
fuente
0

Una variación de la respuesta de Alexey. Un poco más complicado, pero no implica escribir en un archivo de texto:

1) En la ventana Inmediato ingrese:

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

2) En la ventana Watch, ingrese dos relojes:

a.  stringWriter

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

Después de ingresar el segundo reloj (el de Serializar), el valor del reloj de stringWriter se establecerá en obj serializado en XML. Cópialo y pégalo. Tenga en cuenta que el XML se incluirá entre llaves, {...}, por lo que deberá eliminarlo si desea utilizar el XML para cualquier cosa.

Simon Tewsi
fuente