저는 Protobuf-net을 사용하여 직렬화를 위해 binaryformatter를 대체하려고합니다. 나는 여러 가지 문제에 직면 해 있으며 일을하는 데 권장되는 방법이 궁금합니다. 일련 번호를 지정하고 싶습니다. 그들은 솔루션의 여러 프로젝트에 있습니다.binaryformatter를 Protobuf-net으로 바꾸십시오.
직렬화 할 클래스가있는 동일한 프로젝트에서 직렬화를 호출하려고하면 다른 프로젝트에있는 경우 계약을 알지 못해 작동합니다. 우리의 클래스는 다른 프로젝트에 정의 된 유형 (구조체)을 사용합니다. 이 구조체를 사용하여 클래스를 직렬화하려고하면 해당 유형에 대해 알지 못하는 것과 동일한 문제가 발생합니다. PrepareSerializer를 사용하여 수동으로 유형을 추가 할 수 있으며 직렬화 할 것입니다 ...하지만 Deserialize하려고하면 부분적으로 신뢰할 수있는 호출자에 대한 오류가 발생합니다.
또한 프리 컴파일 유틸리티를 사용하려고 시도했지만 클래스는 공용 접근자를 사용하여 private 필드를 사용하므로 private 필드를 처리 할 수 없다는 오류가 발생하여 바이너리 포맷터를 대체 할 수 없습니다.
어떻게 이러한 문제를 해결할 수 있습니까?
"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()
Marc, 나는 사전 컴파일을 시도하고 어떻게되는지 알려줄 것입니다. 다른 (잠재적으로 어리석은) 질문 - 프리 컴파일러로. 개인 필드에 액세스 할 수없는 이유는 무엇입니까? 클래스가 [Protocontract (AllFields)]로 장식되어 있다면 (틀린 문법이지만, 내가 의미하는 것을 안다.), 시리얼 라이저는 아마도 리플렉션을 통해 비공개 필드에 액세스 할 것인가? 왜 프리 컴파일러가 그렇게 할 수 없습니까? –
@Colin은 어셈블리에서 유효하지 않기 때문에 유효성 검사에 실패하고 CLI에 의해 거부됩니다. 그러나'internal' +'[InternalsVisibleTo (...)] 트릭은 CLI와 프리 컴파일러 모두에서 완전히 허용됩니다. Re가 CompileInPlace와 함께 작동하는 이유 : 메모리 내에서 작업 할 때 더 많이 속일 수 있습니다. 정보를 위해서, 이것은'XmlSerializer'가 public 멤버만을 허용하는 이유이기도합니다 - 그것은 어셈블리를 생성합니다. –
프리 컴파일은 내 테스트 프로젝트에서 그 트릭과 함께 작동합니다. 그것을 전체 솔루션에 연결하고 이것이 어떻게 진행되는지보십시오. –