Protobuf net 用Protobuf net替换二进制格式化程序

Protobuf net 用Protobuf net替换二进制格式化程序,protobuf-net,Protobuf Net,我试图用Protobuf net来代替我们对二进制格式化程序进行序列化的使用。我遇到了很多问题,我想知道推荐的做事方式。 我有很多要序列化的类。他们在一个解决方案中的许多项目中 如果我尝试从要序列化的类所在的同一个项目中调用Serialize,它会工作,如果它们在不同的项目中,它会失败,而不知道契约。我们的类还使用在其他项目中定义的类型(结构)。当我们尝试使用这个结构序列化一个类时,在不知道该类型的情况下,我们会遇到同样的问题。我可以使用PrepareSerializer手动添加类型,它将序列化

我试图用Protobuf net来代替我们对二进制格式化程序进行序列化的使用。我遇到了很多问题,我想知道推荐的做事方式。 我有很多要序列化的类。他们在一个解决方案中的许多项目中

如果我尝试从要序列化的类所在的同一个项目中调用Serialize,它会工作,如果它们在不同的项目中,它会失败,而不知道契约。我们的类还使用在其他项目中定义的类型(结构)。当我们尝试使用这个结构序列化一个类时,在不知道该类型的情况下,我们会遇到同样的问题。我可以使用PrepareSerializer手动添加类型,它将序列化…但是当我尝试反序列化时,我得到一个错误,即不允许部分受信任的调用方

我也尝试过使用预编译实用程序,但是我们的类使用带有公共访问器的私有字段,我得到一个错误,它不能处理私有字段,所以我们不能用它来替换二进制格式化程序

我怎样才能避开这些问题

编辑-这是来自部分受信任调用方异常的stacktrace:

"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()

有趣。我在部分信任设置方面做得不多,但如果您能让我知道stacktrace在爆炸时是什么(以及您从何处调用-即调用serialize的程序集是否不同于调用deserialize的程序集),我可能可以添加一些
[AllowPartiallyTrustedCallers]
在一些地方,让它发挥作用

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


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

谢谢Marc,我会尝试预编译,并让您知道它是如何运行的。另一个(可能很愚蠢的)问题是预编译器。为什么它不能访问私有字段?如果一个类用[Protocontract(AllFields)](语法错误,但您知道我的意思),则序列化程序可能会通过反射访问私有字段?为什么预编译器也不能这样做?@Colin,因为这在程序集中是不合法的-它将无法通过验证并被CLI拒绝。内部
+
[InternalsVisibleTo(…)]
技巧,但是,CLI和预编译器都完全允许。Re为什么它与
CompileInPlace
一起工作:当你在内存中做事情时,你可以欺骗更多。关于信息,这也是为什么
XmlSerializer
只允许公共成员-它会生成一个程序集。预编译在我的测试项目中使用这个技巧。将尝试将其插入完整解决方案中,并查看其运行情况。好的,另一个问题。.我们的项目名称为强名称,在InternalsVisibleTo中指定公钥不起作用-它表示不能使用非公共成员。@Colin您需要的internalsvisible密钥可以通过“sn”获取“-参见内部可视属性页面上的MSDN示例