Protobuf-net:如何调试“不支持嵌套或锯齿状列表和数组”

Posted

技术标签:

【中文标题】Protobuf-net:如何调试“不支持嵌套或锯齿状列表和数组”【英文标题】:Protobuf-net: How to debug "Nested or jagged lists and arrays are not supported" 【发布时间】:2017-07-12 15:54:38 【问题描述】:

在序列化过程中出现以下错误:

System.NotSupportedException: Nested or jagged lists and arrays are not supported
   at ProtoBuf.Meta.MetaType.ResolveListTypes(TypeModel model, Type type, Type& itemType, Type& defaultType)
   at ProtoBuf.Meta.MetaType.ApplyDefaultBehaviour(Boolean isEnum, ProtoMemberAttribute normalizedAttribute)
   at ProtoBuf.Meta.MetaType.ApplyDefaultBehaviour()
   at ProtoBuf.Meta.RuntimeTypeModel.FindOrAddAuto(Type type, Boolean demand, Boolean addWithContractOnly, Boolean addEvenIfAutoDisabled)
   at ProtoBuf.Meta.RuntimeTypeModel.GetKey(Type type, Boolean demand, Boolean getBaseKey)
   at ProtoBuf.Meta.ValueMember.TryGetCoreSerializer(RuntimeTypeModel model, DataFormat dataFormat, Type type, WireType& defaultWireType, Boolean asReference, Boolean dynamicType, Boolean overwriteList, Boolean allowComplexTypes)
   at ProtoBuf.Meta.ValueMember.BuildSerializer()
   at ProtoBuf.Meta.MetaType.BuildSerializer()
   at ProtoBuf.Meta.MetaType.get_Serializer()
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteObject(Object value, Int32 key, ProtoWriter writer)
   at proto_20(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteRecursionSafeObject(Object value, Int32 key, ProtoWriter writer)
   at proto_6(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteRecursionSafeObject(Object value, Int32 key, ProtoWriter writer)
   at proto_5(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteObject(Object value, Int32 key, ProtoWriter writer)
   at proto_84(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteRecursionSafeObject(Object value, Int32 key, ProtoWriter writer)
   at proto_32(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteRecursionSafeObject(Object value, Int32 key, ProtoWriter writer)
   at proto_5(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteObject(Object value, Int32 key, ProtoWriter writer)
   at ProtoBuf.BclHelpers.WriteNetObject(Object value, ProtoWriter dest, Int32 key, NetObjectOptions options)
   at proto_150(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteRecursionSafeObject(Object value, Int32 key, ProtoWriter writer)
   at proto_147(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteObject(Object value, Int32 key, ProtoWriter writer)
   at proto_26(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteRecursionSafeObject(Object value, Int32 key, ProtoWriter writer)
   at proto_6(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteRecursionSafeObject(Object value, Int32 key, ProtoWriter writer)
   at proto_5(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteObject(Object value, Int32 key, ProtoWriter writer)
   at proto_8(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteRecursionSafeObject(Object value, Int32 key, ProtoWriter writer)
   at proto_6(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteRecursionSafeObject(Object value, Int32 key, ProtoWriter writer)
   at proto_5(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteObject(Object value, Int32 key, ProtoWriter writer)
   at ProtoBuf.BclHelpers.WriteNetObject(Object value, ProtoWriter dest, Int32 key, NetObjectOptions options)
   at proto_142(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteRecursionSafeObject(Object value, Int32 key, ProtoWriter writer)
   at proto_141(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteObject(Object value, Int32 key, ProtoWriter writer)
   at proto_139(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteObject(Object value, Int32 key, ProtoWriter writer)
   at ProtoBuf.BclHelpers.WriteNetObject(Object value, ProtoWriter dest, Int32 key, NetObjectOptions options)
   at proto_80(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteRecursionSafeObject(Object value, Int32 key, ProtoWriter writer)
   at proto_32(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteRecursionSafeObject(Object value, Int32 key, ProtoWriter writer)
   at proto_5(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteObject(Object value, Int32 key, ProtoWriter writer)
   at proto_137(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.ProtoWriter.WriteObject(Object value, Int32 key, ProtoWriter writer)
   at proto_1(Object , ProtoWriter )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write(Object value, ProtoWriter dest)
   at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest)
   at ProtoBuf.Meta.TypeModel.SerializeCore(ProtoWriter writer, Object value)
   at ProtoBuf.Meta.TypeModel.Serialize(Stream dest, Object value, SerializationContext context)
   at ProtoBuf.Serializer.Serialize[T](Stream destination, T instance)

我看到了问题,但是在哪里,什么类型?任何建议如何找到它?

我尝试搜索 Dictionary< List< 并查看其中的内容,但没有运气。

InnerExceptionnull

我曾尝试拨打ProtoBuf.Meta.RuntimeTypeModel.Default.GetSchema(typeof(LinkBudgetScenario)); 相同的无用消息。

是否有可能获得更有用的错误消息而不是内部无用的调试消息?

【问题讨论】:

如果在 Visual Studio 中调试,打开“抛出异常时中断”,然后检查该调用堆栈上的参数,怎么样?您可能没有源代码,但参数应该仍然很容易获得。如果做不到这一点,您可以从 github 上查看 protobuf-net 并将其添加到您的解决方案中,从而获得源代码。 @DarkFalcon,我有源代码,但源对象真的很大。我试图带上 protobuf 源代码,但还有另一个问题。 VS 2017 上的 Protobuf,VS 15 上的项目。是的,我可以安装 VS 17,将我们的项目转换为 VS 17。只是,想知道,也许有简单的方法 :) 感谢 .Net 反射器,我找到了问题所在。它允许调试第三方库。顺便说一句,它是List<Lobe2d>[] 【参考方案1】:

步骤:

    更新到 protobuf-net 2.3.0:https://www.nuget.org/packages/protobuf-net/2.3.0 重新运行代码并阅读消息

【讨论】:

是否也可以改善错误:Multi-dimensional arrays are not supported?目前,它没有说错误在哪里,什么字段:(【参考方案2】:

解决问题的步骤:

    尝试查看源对象。 (如果运气不好goto 2) 将Protobuf-net 源代码添加到您的解决方案中(如果运气不好goto 3) 安装.net reflector并开启调试功能,不要忘记停止所有异常(Debug -> Windows -> Exception Settings)。现在您可以确定问题类型了。

【讨论】:

以上是关于Protobuf-net:如何调试“不支持嵌套或锯齿状列表和数组”的主要内容,如果未能解决你的问题,请参考以下文章

protobuf-net:如何注释派生类型的属性?

使用protobuf-net继承时如何选择字段号?

如何使用 protobuf-net 扩展?

如何使用 protobuf-net 读回附加的对象?

如何使用 protobuf-net 处理 .proto 文件

protobuf-net 如何序列化 DateTime?