2012-06-12 13 views
7

Ja próbuje serializacji wykresu obiektu w .NET z następującą metodą:Jak zidentyfikować pole powodujące, że serializacja binarna zawiedzie w .NET?

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

Jednakże używam w następujący błąd:

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) 

Czy istnieje prosty sposób określić, które pole produkuje ten błąd? Mogłem rekurencyjnie oznaczyć pola na wykresie obiektu jako NonSerialized, aby zawęzić potencjalnych winowajców, ale ponieważ wykres obiektów jest dość obszerny, jest to uciążliwe i wydaje się niepotrzebne.

Należy zauważyć, że nie jestem pewien, dlaczego BinaryFormatter nie może serializować jednej lub więcej wartości na wykresie obiektu. Jeśli obiekt może być przechowywany w pamięci w środowisku wykonawczym, nie jest jasne, dlaczego nie można go serializować. Czy to może być problem z wyliczeniem?

Odpowiedz

6

Użyj Windbg. Pobierz go: here (wybierz tylko instalator z debuggera, nie musisz go aktualizować) i uruchom go.

Następnie użyj File - Open Executable - i uruchom. Złamiesz się na wyjątku w debugerze. Jeśli nie, wybierz przed uruchomieniem, aby włączyć punkt przerwania dla każdego zarządzanego wyjątku. Następnie należy wpisać:

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

Zostanie wyświetlona lista obiektów, które były używane przez bieżący wątek, zanim uległy awarii. Następnie klikasz jedną z niebieskich podkreślonych instancji NameInfo, aby sprawdzić, w której z nich zmienna nie działa. Zgadzam się, że wymaga to trochę cierpliwości, aby się tego nauczyć, ale możesz debugować takie rzeczy w rekordowym czasie, podczas gdy inni muszą bawić się w swoim kodzie, aby zdusić problem. Wszystko, co musisz zrobić, to zajrzeć do instancji NameInfo, która spowodowała problem.

+0

Przepraszamy za długie opóźnienie w zaakceptowaniu tego. Nigdy nie miałem czasu zweryfikować tego podejścia, ale ponieważ zapewnia ono wgląd w potencjalnie przydatne narzędzie, którego nie znałem, myślę, że ta odpowiedź jest najbardziej przydatna/obiecująca. – mcliedtk

+0

Użyłem tego do debugowania dużej zmiany modelu danych, który jest serializowany i szybko wskazał mi właściwy kierunek. Po przerwaniu poprawnego wyjątku możesz użyć! Clrstack -p, aby uzyskać zrzut śledzenia stosu ze wskaźnikami do parametrów. W moim przypadku wiele z nich nie posiadało żadnych danych, ale dalej na stosie zawierało wskaźnik do serializowanego obiektu. –

-1

Skomentuj wszystkie właściwości i serializuj obiekt. Reintroduce je jeden po drugim, aż błąd powróci.

To jest podstawowe debugowanie.

Śledzenie stosu daje wskazówki, jeśli nie ma wielu typów serializacji.

+0

Tak, to jest podstawowe debugowanie i być może nie było jasne w moim pierwotnym pytaniu, ale czekam na alternatywę dla tego podejścia. Wykres obiektowy jest dość szeroki i głęboki i liczyłem na skrót. – mcliedtk

+0

@mcliedtk Miałem podobny problem z serią Json. Odpowiedź była prawie zawsze "Ostatnie pole/właściwość, którą dodałeś" – asawyer

+0

Dobra uwaga. Zajrzę do historii źródłowej, aby zobaczyć, czy jest jakaś oczywista zmiana, ale niestety mam do czynienia z bardzo dużym wykresem obiektów, który obejmuje wiele plików, więc może to zająć trochę badań. Dzięki za sugestie. – mcliedtk

3

Sposób, w jaki się do tego zbliżyłem, polegał na serializacji obiektu do ciągu znaków, a następnie zapisaniu ciągu znaków w pliku. Możesz następnie spojrzeć na ciąg serializowany, zobaczyć, gdzie się zatrzymał, i wyprowadzić stamtąd element, który spowodował problem.

+0

Sprytnie ... Dam ci spróbować. – mcliedtk

Powiązane problemy