你如何确定导致二进制序列化在.NET中失败的领域?领域、序列化、NET

2023-09-03 16:44:18 作者:酒意入桃枝

我试图对象图在.NET中使用下面的方法序列化:

I am attempting to serialize an object graph in .NET with the following method:

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

不过,我遇到了以下错误:

However, I am running into the following 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)

有没有一种简单的方法来确定哪些领域正在产生这个错误?我可以递归地标记在对象图中的字段作为非序列化来缩小潜在元凶,但作为对象图是相当广泛的,这是繁重的,似乎不必要。

Is there a straightforward way to identify which field is producing this error? I could recursively mark the fields in the object graph as NonSerialized to narrow down potential culprits, but as the object graph is quite extensive, this is burdensome and seems unnecessary.

请注意,我不知道为什么BinaryFormatter的不能在对象图序列化的一个或多个值。如果对象可以在运行时被存储在存储器,目前尚不清楚为什么它不能序列。难道这是一个问题,一个枚举?

Note that I am not sure why the BinaryFormatter cannot serialize one or more values in the object graph. If the object can be stored in memory at runtime, it is not clear why it cannot be serialized. Could this be a problem with an enum?

推荐答案

使用WinDbg。下载这里(从安装程序只选择调试器。你不需要downlad完整的SDK),并启动它。

Use Windbg. Download it here (select from the installer only the debugger. You do not need to downlad the complete SDK) and start it.

然后使用文件 - 打开可执行 - 并启动它。你会在异常在调试器打破。如果不是,然后再开始选择

Then use File - Open Executable - and start it. You will break at the exception in the debugger. If not select before you start

Debug - Event Filters - CLR Exception - Enabled

要在每个托管异常启用断点。然后,你需要键入

to enable a breakpoint on every managed exception. Then you need to type

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

这会给你这是由当前线程之前,它会失败的对象列表。然后你点击蓝色的一个突出NameInfo实例,看看这在其成员变量序列化会​​失败。我同意它需要一些耐心去学习,但你可以在最短的时间调试这样的东西,在别人需要反复折腾他们的code钉的问题。所有你需要做的是寻找到NameInfo实例,它确实导致了问题。

This will give you a list with the objects which were used by the current thread before it did fail. Then you click on one of the blue underlined NameInfo instances to see which at which member variable the serializer did fail. I agree that it requires some patience to learn but you can debug such stuff in record time where others need to fiddle around in their code to nail the issue. All you need to do is to look into the NameInfo instance which did cause the issue.