2012-06-12 10 views
7

Sto tentando di serializzare un oggetto grafico nel .NET con il seguente metodo:Come si identifica il campo che causa il fallimento della serializzazione binaria in .NET?

public static byte[] Serialize(object data) 
{ 
    var binary = new BinaryFormatter(); 
    using (var ms = new MemoryStream()) { 
     binary.Serialize(ms, data); 
     return ms.ToArray(); 
    } 
} 

Tuttavia, sono in esecuzione nella seguente errore:

FormatException: Input string was not in a correct format. 
Stack Trace: 
    at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) 
    at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info) 
    at System.String.System.IConvertible.ToInt32(IFormatProvider provider) 
    at System.Convert.ToInt32(Object value, IFormatProvider provider) 
    at System.Runtime.Serialization.Formatters.Binary.__BinaryWriter.WriteValue(InternalPrimitiveTypeE code, Object value) 
    at System.Runtime.Serialization.Formatters.Binary.__BinaryWriter.WriteMember(NameInfo memberNameInfo, NameInfo typeNameInfo, Object value) 
    at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteKnownValueClass(NameInfo memberNameInfo, NameInfo typeNameInfo, Object data) 
    at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteMembers(NameInfo memberNameInfo, NameInfo memberTypeNameInfo, Object memberData, WriteObjectInfo objectInfo, NameInfo typeNameInfo, WriteObjectInfo memberObjectInfo) 
    at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteMemberSetup(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo, String memberName, Type memberType, Object memberData, WriteObjectInfo memberObjectInfo) 
    at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo, String[] memberNames, Type[] memberTypes, Object[] memberData, WriteObjectInfo[] memberObjectInfos) 
    at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo) 
    at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) 
    at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) 

C'è un modo semplice per identificare quali il campo sta producendo questo errore? Potrei ricorsivamente contrassegnare i campi nel grafo degli oggetti come NonSerialized per restringere i potenziali colpevoli, ma poiché il grafo degli oggetti è piuttosto esteso, questo è oneroso e sembra non necessario.

Nota che non sono sicuro del perché il BinaryFormatter non possa serializzare uno o più valori nel grafico dell'oggetto. Se l'oggetto può essere memorizzato in memoria al runtime, non è chiaro il motivo per cui non può essere serializzato. Questo potrebbe essere un problema con un enum?

risposta

6

Utilizzare Windbg. Scaricalo nel here (seleziona dal programma di installazione solo il debugger. Non è necessario scaricare l'SDK completo) e avviarlo.

Quindi utilizzare File - Open Executable - e avviarlo. Si interromperà all'eccezione nel debugger. Se non si seleziona prima di iniziare

Debug - Event Filters - CLR Exception - Enabled 

per abilitare un punto di interruzione su ogni eccezione gestita. Quindi devi digitare

.loadby sos clr 
(if you are using .NET 3.5 .loadby sos mscorwks) 
.prefer_dml 1 
!dso 

Questo ti darà una lista con gli oggetti che sono stati utilizzati dal thread corrente prima che fallisse. Quindi fai clic su una delle istanze NameInfo sottolineate in blu per vedere quale a quale variabile membro ha fallito il serializzatore. Sono d'accordo sul fatto che è necessario un po 'di pazienza per imparare, ma è possibile eseguire il debug di queste cose in un tempo record in cui gli altri hanno bisogno di giocherellare nel loro codice per inchiodare il problema. Tutto quello che devi fare è esaminare l'istanza NameInfo che ha causato il problema.

+0

Ci scusiamo per il lungo ritardo nell'accettare questo. Non ho mai avuto il tempo di verificare questo approccio, ma poiché fornisce informazioni su uno strumento potenzialmente utile di cui non ero a conoscenza, penso che questa risposta sia la più utile/promettente. – mcliedtk

+0

L'ho usato per eseguire il debug di una grande modifica al modello di dati serializzato e mi ha indirizzato rapidamente nella giusta direzione. Una volta interrotta l'eccezione corretta, è possibile utilizzare! Clrstack -p per ottenere un dump della traccia dello stack con i puntatori ai parametri. Per il mio caso molti di loro non avevano dati, ma più in alto lo stack conteneva un puntatore all'oggetto che veniva serializzato. –

-1

Commenta tutte le proprietà e serializza l'oggetto. Reintrodurli uno alla volta fino a quando l'errore non ritorna.

Questo è il debug di base.

La traccia di stack fornisce tuttavia suggerimenti, se non ci sono molti tipi di serializzazione.

+0

Sì, questo è il debug di base, e forse non ero chiaro nella mia domanda iniziale, ma non vedo l'ora di un'alternativa a questo approccio. Il grafico dell'oggetto è abbastanza ampio e profondo e speravo in una scorciatoia. – mcliedtk

+0

@mcliedtk Ho avuto un problema simile con una serializzazione Json. La risposta era quasi sempre "L'ultimo campo/proprietà che hai aggiunto" – asawyer

+0

Buon punto. Guarderò nella cronologia delle fonti per vedere se c'è un cambiamento evidente, ma sfortunatamente ho a che fare con un grafo di oggetti molto grande che copre molti file, quindi questo potrebbe richiedere qualche indagine. Grazie per i suggerimenti. – mcliedtk

3

Il modo in cui mi sono avvicinato era serializzare l'oggetto in una stringa e quindi scrivere la stringa in un file. È quindi possibile esaminare la stringa serializzata, vedere dove si è fermato e dedurre da lì quale elemento ha causato il problema.

+0

Intelligente ... Darò una prova. – mcliedtk

Problemi correlati