用Protobuf-net替换binaryformatter

时间:2012-11-19 04:04:38

标签: protobuf-net

我正在尝试用Protobuf-net替换我们使用binaryformatter进行序列化。我遇到了很多问题,我想知道推荐的做事方式。 我有一些(很多)我要序列化的类。他们在一个解决方案的许多项目中。

如果我尝试从要序列化的类所在的同一个项目中调用Serialize,它可以工作,如果它们在不同的项目中,则会失败,不知道合同。我们的类也使用其他项目中定义的类型(结构)。当我们尝试使用这个结构序列化一个类时,我们遇到的问题是它不知道该类型。我可以使用PrepareSerializer手动添加类型,它将序列化...但是当我尝试反序列化时,我得到一个关于不允许部分信任的调用者的错误。

我也尝试使用预编译实用程序,但是我们的类使用带有公共访问器的私有字段,并且我收到错误,说它无法处理私有字段,所以我们不能用它来替换二进制格式化程序? / p>

我如何解决这些问题?

编辑 - 这是部分受信任的调用者异常的堆栈跟踪:

"That assembly does not allow partially trusted callers."
at proto_4(Object , ProtoReader )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value, ProtoReader source)
   at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source)
   at ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type)
   at ProtoBuf.ProtoReader.ReadObject(Object value, Int32 key, ProtoReader reader)
   at proto_2(Object , ProtoReader )
   at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value, ProtoReader source)
   at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source)
   at ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoReader reader, Type type, Object value, Boolean noAutoCreate)
   at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type, SerializationContext context)
   at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type)
   at ProtoBuf.Serializer.Deserialize[T](Stream source)
   at BinarySerializationTest.Form1.button1_Click(Object sender, EventArgs e)
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at BinarySerializationTest.Program.Main()
   at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

1 个答案:

答案 0 :(得分:0)

有趣。我没有做过部分信任设置,但是如果你能告诉我当堆栈跟踪爆炸时它是什么(以及你在哪里调用 - 即调用序列化的程序集是否与调用反序列化的程序集不同),我可能会在一些地方添加一些[AllowPartiallyTrustedCallers]以使其有效。

预编译路由是我的另一个建议,但实际上这不适用于私有字段,因为独立程序集上的可访问性更加严格。

第三种选择是将受影响的private字段设置为internal字段,并使用[assembly:InternalsVisibleTo("NameOfGeneratedAssembly)]使这些字段可访问 - 然后使用“预编译器”。然后,这可以访问字段,并从r602开始支持(这是撰写本文时的最新版本)。