2014-01-30 45 views
1

我想編寫一個C#客戶端通過protobuf網發送一個字符串到TCP服務器(實施)。但是,當我嘗試使用protobuf-net序列化字符串時,我得到一個TypeInitializerException「'Singleton'的類型初始值設定項引發了一個異常。」錯誤序列化使用protobuf網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.儘管如此,錯誤是什麼? –

回答

1

我不能重現它示數;你的代碼,直接複製,做工精細:

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

但是,要盡力幫助:

  • 第一,catchException,並期待在.InnerException。更多信息可用於大多數例外;例如:

    try { 
        // HERE: the code that errors 
    } catch(Exception ex) { 
        while(ex != null) { 
         Console.Error.WriteLine(ex.Message); 
         ex = ex.InnerException; 
        } 
        throw; 
    } 
    
  • 其次,注意與遺傳模型一個常見的問題是不宣佈繼承 - 看看是否可能是基類需要的裝飾,例如:

    [ProtoInclude(1, typeof(Message))] 
    
  • 另一個觀察是缺乏一個公共無參數構造函數;現在,protobuf網不堅持就此(事實上,它看起來像它是在問題中的代碼作爲「自動元組」,並使用存在的構造函數),但你也可以提供一個額外的(可能非公有制)參數的構造函數:

    private Message() {} 
    

    或告訴它完全跳過構造函數:

    [ProtoContract(SkipConstructor = true)] 
    

不過:不知道異常信息是什麼,這是很難比這更推測。

+0

感謝和+1。添加try/catch幫助,錯誤是我需要項目中的「IKVM.Reflection」引用。我現在在「錯誤:指定的方法不支持」在同一行中拋出。 –

+1

@La哇!停止!你永遠不應該需要這個。我想知道你是否引用了錯誤的dll。 IKVM僅由預編譯器使用。如果你可以顯示某種程度上取決於IKVM的代碼,那麼我需要儘快解決這個問題。但我想你已經從預編譯器引用了dll。不要那樣做;他們有區別。 –

+0

你是指通過引用錯誤的DLL是什麼意思?我應該參考什麼?順便說一下,我在程序中刪除了對IKVM的引用,但仍然收到錯誤「指定的方法不受支持」。 –