2014-01-30 2 views
1

protobuf-net을 통해 문자열을 TCP 서버 (구현 됨)에 보내려면 C# 클라이언트를 작성하고 싶습니다. 그러나 protobuf-net을 사용하여 문자열을 serialize하려고하면 TypeInitializerException " 'Singleton'의 형식 이니셜 라이저에서 예외가 발생했습니다." 성공하지 않고,이 사이트 및 다른 사람에 의해 조언 접근 방법을 시도했습니다protobuf-net을 사용하여 C# 문자열을 직렬화하는 중 오류가 발생했습니다.

public static void TelnetConnect(string host, int port) { 
    ... 
    Message msg = new Message("This is a test."); 
    byte[] sentbytes = msg.Serialize(); 
    ... 
} 

[ProtoContract] 
public abstract class MessageI { 
    public byte[] Serialize() { 
     byte[] result; 
     using (var stream = new MemoryStream()) { 
      Serializer.Serialize(stream, this); //THIS LINE THROWS EXCEPTION 
      result = stream.ToArray(); 
     } 
     return result; 
    } 
} 

[ProtoContract] 
public class Message : MessageI { 
    [ProtoMember(1)] 
    public string str { get; set; } 

    public Message(string s) { 
     this.str = s; 
    } 
} 

: 여기

는 코드입니다. 저는 Visual Studio 2010에서 C#을 사용하고 있습니다.

고마워, 대단히 감사합니다.

UPDATE : 스택 추적 :

at ProtoBuf.Meta.RuntimeTypeModel.get_Default() 
    at ProtoBuf.Serializer.Serialize[T](Stream destination, T instance) 
    at PingNorbertServer.MessageI.Serialize() in C:\Users\RS88517\Documents\Visual Studio 2010\Projects\PingNorbertServer\PingNorbertServer\NorbertClient.cs:line 37 
    at PingNorbertServer.NorbertClient.TelnetConnect(String host, Int32 port) in C:\Users\RS88517\Documents\Visual Studio 2010\Projects\PingNorbertServer\PingNorbertServer\NorbertClient.cs:line 23 
    at PingNorbertServer.NorbertClient.Main(String[] args) in C:\Users\RS88517\Documents\Visual Studio 2010\Projects\PingNorbertServer\PingNorbertServer\NorbertClient.cs:line 14 
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly 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, Boolean ignoreSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart() 
+0

나는 Singleton 클래스가 무엇인지 모르지만 아마도 MemoryStream, Serializer 또는 Message 일 것이다. –

+1

이 예외는 일반적으로 오류를 발생시키는 정적 생성자가 호출 될 때 발생합니다. 디버거가 자동으로 정적 생성자 ("Singleton"으로 추정 됨)로 이동하지 않으므로 스택 추적을보고 실제 오류 – jcharlesworthuk

+0

을 찾으면됩니다. 오류가 발생했습니다. –

답변

1

내가 erroring을 재현 할 수 없습니다;

static void Main() 
{ 
    var data = new Message("abc").Serialize(); 
} 

을하지만, 도움이 시도 : 직접 복사 코드는 잘 작동

  • 먼저 catchException을하고 .InnerException 봐. 대부분의 예외에 대해 더 많은 정보가 제공됩니다. 예를 들면 : - :

    [ProtoInclude(1, typeof(Message))] 
    
  • try { 
        // HERE: the code that errors 
    } catch(Exception ex) { 
        while(ex != null) { 
         Console.Error.WriteLine(ex.Message); 
         ex = ex.InnerException; 
        } 
        throw; 
    } 
    
  • 둘째
  • 는, 상속 모델과 공통의 문제가 상속을 선언하지 있습니다 아마도 기본 클래스 예를 들어, 장식을해야하는지 여부를 살펴 또 다른 관찰은 매개 변수없는 public 생성자가 없다는 것입니다. 이제 protobuf-net은 을 주장하지 않습니다 (실제로 자동 터플로 질문의 코드를 처리하고 존재하는 생성자를 사용하는 것처럼 보입니다). 추가 (아마도 비공개) 매개 변수가없는 생성자 :

    private Message() {} 
    

    또는 완전히 생성자를 생략하도록 지시 :

    [ProtoContract(SkipConstructor = true)] 
    

그러나 : 예외 메시지가 무엇인지 모르고, 그것은 하드입니다 이것보다 더 추측해라.

+0

감사합니다. +1. try/catch를 추가하는 것이 도움이되었고 오류는 프로젝트에서 "IKVM.Reflection"참조가 필요하다는 것입니다. 지금 "오류 : 지정된 메서드가 지원되지 않습니다."같은 줄에 throw됩니다. –

+1

@La woah! 중지! 절대 절대로 그렇게해서는 안됩니다. 내가 잘못 dll을 참조했는지 궁금하다. IKVM은 프리 D 파일러에서만 사용됩니다.어떻게 든 IKVM에 의존하는 코드를 표시 할 수 있다면 가능한 빨리 수정해야합니다. 하지만 난 당신이 precompiler에서 DLL을 참조했다고 생각합니다. 그렇게하지 마라. 그것은 다르다. –

+0

잘못된 dll을 참조하여 무엇을 의미합니까? 무엇을 참조해야합니까? 그런데 프로그램에서 IKVM에 대한 참조를 제거했지만 "지정된 메소드가 지원되지 않습니다."라는 오류가 발생했습니다. –