2012-06-12 11 views
7

que estoy tratando de serializar un gráfico de objetos en .NET con el siguiente método:¿Cómo identifica el campo que está causando que la serialización binaria falle en .NET?

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

Sin embargo, estoy corriendo en el siguiente error:

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) 

¿Hay una manera fácil de identificar qué el campo está produciendo este error? Podría marcar recursivamente los campos en el gráfico de objeto como NonSerialized para reducir los posibles culpables, pero como el gráfico de objeto es bastante extenso, esto es engorroso y parece innecesario.

Tenga en cuenta que no estoy seguro de por qué BinaryFormatter no puede serializar uno o más valores en el gráfico de objetos. Si el objeto se puede almacenar en la memoria en tiempo de ejecución, no está claro por qué no se puede serializar. ¿Podría ser esto un problema con una enumeración?

Respuesta

6

Utilice Windbg. Descárguelo here (seleccione desde el instalador solo el depurador. No necesita descargar el SDK completo) e inícielo.

Luego use File - Open Executable - y enciéndalo. Se romperá en la excepción en el depurador. Si no, seleccione antes de comenzar

Debug - Event Filters - CLR Exception - Enabled 

para habilitar un punto de interrupción en cada excepción gestionada. Luego debe escribir

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

Esto le dará una lista con los objetos que fueron utilizados por el hilo actual antes de que fallara. A continuación, hace clic en una de las instancias NameInfo subrayadas en azul para ver en qué variable de miembro falló el serializador. Estoy de acuerdo en que requiere algo de paciencia para aprender, pero puede depurar tales cosas en un tiempo récord donde otros necesitan manipular su código para resolver el problema. Todo lo que necesita hacer es buscar en la instancia de NameInfo que causó el problema.

+0

Disculpa por la gran demora en aceptar esto. Nunca tuve tiempo de verificar este enfoque, pero dado que proporciona información sobre una herramienta potencialmente útil de la que no tenía conocimiento, creo que esta respuesta es la más útil/prometedora. – mcliedtk

+0

Lo he usado para depurar un gran cambio en el modelo de datos que se está serializando y rápidamente me apuntó en la dirección correcta. Una vez que tenga un descanso en la excepción correcta, puede usar! Clrstack -p para obtener un volcado del rastreo de la pila con punteros a los parámetros. Para mi caso, muchos de ellos no tenían datos, pero más arriba en la pila contenía un puntero al objeto que se serializaba. –

-1

Comenta todas las propiedades y serializa el objeto. Reintrodúzcalos uno a la vez hasta que vuelva el error.

Esto es una depuración básica.

El rastro de la pila da pistas, si no hay muchos tipos que se serializan.

+0

Sí, esto es una depuración básica, y tal vez no estaba claro en mi pregunta original, pero estoy esperando una alternativa a este enfoque. El gráfico de objetos es bastante amplio y profundo y esperaba un atajo. – mcliedtk

+0

@mcliedtk Tuve un problema similar con una serialización Json. La respuesta casi siempre fue "El último campo/propiedad que agregó" – asawyer

+0

Buen punto. Buscaré en el historial de fuentes para ver si hay un cambio obvio, pero desafortunadamente estoy tratando con un gráfico de objetos muy grande que cubre muchos archivos, por lo que puede llevar algo de investigación. Gracias por las sugerencias. – mcliedtk

3

La forma en que me acerqué a esto fue serializar el objeto en una cadena y luego escribir la cadena en un archivo. Luego puede ver la cadena serializada, ver dónde se detuvo e inferir a partir de allí qué elemento causó el problema.

+0

Inteligente ... Lo intentaré. – mcliedtk

Cuestiones relacionadas