Visual Studio como serializar o objeto do depurador

88

Estou tentando investigar um bug em um despejo de memória (portanto, não posso alterar o código). Tenho um objeto realmente complicado (milhares de linhas na representação serializada) e seu estado é inconsistente. Para investigar seu estado, a visualização do depurador do Visual Studio é inútil. Mas o objeto tem um contrato de dados. Gostaria de serializá-lo e usar meu editor de texto favorito para navegar pelo objeto. É possível fazer a partir do depurador?

xvorsx
fonte
Observe que se você tiver alguma classe de contêiner personalizada ou alguma outra classe que deseja ver muitas vezes durante a depuração, mas o IntelliSense e QuickView não conseguem descobrir, você pode escrever uma extensão para VS que ajuda a mostrar sua classe personalizada em depurar.
Csaba Toth
Muitas técnicas boas também podem ser encontradas [aqui] ( stackoverflow.com/questions/360277/… )
Josh

Respostas:

86

Algum tempo atrás eu escrevi este one-liner serializando um objeto para um arquivo no disco. Copie / cole na janela Immediate e substitua obj(é referenciado duas vezes) pelo seu objeto. Ele salvará um text.xmlarquivo em c:\temp, altere-o ao seu gosto.

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

Não espere nenhuma mágica, porém, se o objeto não puder ser serializado, ele lançará uma exceção.

Alexey
fonte
3
Isso funcionou para mim na janela imediata. voto positivo,
Pankaj Kumar
1
quando eu uso isso na janela imediata do VS 2015, recebo este 'erro': "A avaliação de métodos nativos neste contexto não é suportada." Ideias?
Vetras de
Quando o executo, recebo a seguinte mensagem:identifier "System" is undefined
Rasoul
Tinha um projeto VB.NET antigo, tinha que colocar desta forma, caso contrário eu estava recebendo um erro sobre a sintaxe da expressão, se alguém precisar: new System.Xml.Serialization.XmlSerializer (obj.GetType ()). Serialize (New System.IO .StreamWriter ("C: \ temp \ temp.txt"), obj)
Liquid Core
Isso é espetacular. Tive que usar um diretório diferente devido às permissões de gravação, mas funcionou perfeitamente. Importe para o Excel e é ainda mais bonito.
BuddyZ
160

Com alguma sorte, você já tem Json.Net em seu appdomain. Nesse caso, coloque-o na janela Imediata:

Newtonsoft.Json.JsonConvert.SerializeObject(someVariable)

mcintyre321
fonte
19
Gostaria de poder votar a favor novamente, especialmente em comparação com as outras respostas (Desculpe, mas não preciso ver outra linha de XML em minha carreira.)
yzorg
1
Depois de uma sessão de depuração de teste muito longa, uma exceção aconteceu em meu programa antes que ele pudesse gravar milhares de resultados de teste em um arquivo, eu estava em um ponto de interrupção onde a exceção ocorreu e ainda poderia inspecionar a coleção de resultados. Essa dica me economizou muito tempo!
HAL9000 01 de
1
Talvez você precise usar Json.Net em outro lugar também para que seja carregado quando você tentar usá-lo na janela Imediata (em vez de apenas adicionar a referência).
Evan
1
Tive que adicionar o pacote Newtonsoft.Json usando Nuget e também adicionar uma linha de código no método em que tinha o ponto de interrupção para criar uma classe Newtonsoft.Json.JsonArrayAttribute () fictícia para fazê-lo funcionar. Uma excelente solução!
Richard Moore
1
Esta é uma ótima resposta. Eu o uso com apenas uma pequena mudança para me poupar uma viagem para o embelezador. Newtonsoft.Json.JsonConvert.SerializeObject (someVariable, Newtonsoft.Json.Formatting.Indented)
Jamie
37

Aqui está uma extensão do Visual Studio que permitirá que você faça exatamente isso:

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

Você pode enviar para JSON, XML ou C #

Omar Elabd
fonte
4
Esse link parece estar quebrado, mas aqui está o projeto github e você pode encontrá-lo se pesquisar por "Exportador de objeto" na caixa de diálogo "Extensões e atualizações ..." no Visual Studio. Grande extensão btw!
Niklas Söderberg
2
Obrigado @Omar A ideia é perfeita. Mas leva muito tempo e congela em alguns casos
Wahid Bitar
1
Concordo com @WahidBitar - Ótimo conceito - perfeito para configurar dados de teste de unidade, mas a extensão parece bastante problemática e leva o Visual Studio consigo quando trava!
Dib
Esta é realmente uma ferramenta muito útil.
Ashutosh Singh
4

Use isso na janela "Imediata" do Visual Studio, substituindo c:\directory\file.jsonpelo caminho completo para o arquivo no qual você gostaria de escrever o JSON e myObjectpela sua variável para serializar:

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

Tenho um método de extensão 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);
    }
}

Eu o sobrecarrego com uma string para saveTo e o chamo da janela imediata:

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

Pode ser possível usar a janela imediata para serializá-lo e, em seguida, copiar o conteúdo para seu editor favorito.

Outra opção é substituir o ToString()método e chamá-lo enquanto estiver no modo de depuração.

Você também pode gravar o conteúdo em um arquivo logo antes do travamento ou agrupar o código em um try / catch e gravar o arquivo então. Presumo que você possa identificar quando ele está travando.

Chuck Conway
fonte
Obrigado, tentei o mesmo na janela Watch, mas me disse "A avaliação da função requer que todos os threads sejam executados." Janela imediata para resolver
xvorsx
1

Uma variação da resposta de Omar Elabd -

Não é gratuito, mas existe uma versão de avaliação gratuita do OzCode
( https://marketplace.visualstudio.com/items?itemName=CodeValueLtd.OzCode ).

Há exportação embutida para JSON dentro do menu context / hover lá, e funciona um pouco melhor do que a extensão Object Export (a compensação por não ser gratuita).

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

Sei que isso aconteceu alguns anos depois do ocorrido, mas estou deixando uma resposta aqui porque funcionou para mim e outra pessoa pode achar útil.

Michael Armes
fonte
1

Caso você tenha uma referência circular, execute-a na janela imediata:

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

Tenho usado ObjectDumper.Net .

Funciona bem, especialmente se você tiver testes de unidade ao vivo. Posso visualizar facilmente o valor de uma variável no console quando um teste é executado, evitando a depuração manual.

Isso pode ajudar se você estiver usando o XUnit.

DharmaTurtle
fonte
0

Uma variação da resposta de Alexey. Um pouco mais complicado, mas não envolve gravar em um arquivo de texto:

1) Na janela imediata, digite:

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

2) Na janela de observação, insira duas vigias:

a.  stringWriter

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

Depois de inserir a segunda observação (a Serializar), o valor da observação stringWriter será definido como obj serializado para XML. Copie e cole. Observe que o XML estará entre colchetes, {...}, portanto, você precisará removê-los se quiser usar o XML para qualquer coisa.

Simon Tewsi
fonte