【问题标题】:Error serializing C# string using protobuf-net使用 protobuf-net 序列化 C# 字符串时出错
【发布时间】:2014-01-30 23:43:08
【问题描述】:

我想编写一个 C# 客户端,通过 protobuf-net 将字符串发送到 TCP 服务器(已实现)。但是,当我尝试使用 protobuf-net 序列化字符串时,我收到了 TypeInitializerException“'Singleton' 的类型初始化程序引发了异常。”

代码如下:

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#。

谢谢,非常感谢您的帮助。

更新:堆栈跟踪是:

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

【问题讨论】:

  • 我不知道 Singleton 类是什么,但它可能是 MemoryStream、Serializer 或 Message。
  • 此异常通常发生在调用静态构造函数时抛出错误。您的调试器不会自动将您带入静态构造函数(可能是“Singleton”),因此您需要查看堆栈跟踪以找到真正的错误
  • 谢谢,up 1。但是错误是什么?
  • catch 异常查看.InnerException; .InnerException 会告诉你发生了什么,以及为什么

标签: c# sockets serialization protobuf-net


【解决方案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-net 并没有坚持(事实上,看起来它正在将问题中的代码视为“自动元组”,并使用存在的构造函数),但是你也可以提供一个额外的(可能是非公开的)无参数构造函数:

    private Message() {}
    

    或者告诉它完全跳过构造函数:

    [ProtoContract(SkipConstructor = true)]
    

但是:在不知道异常消息是什么的情况下,很难进一步推测。

【讨论】:

  • 感谢和 +1。添加 try/catch 有帮助,错误是我需要项目中的“IKVM.Reflection”引用。我现在在同一行抛出“错误:不支持指定的方法”。
  • @La woah!停止!你永远不应该需要那个。我想知道您是否引用了错误的dll。 IKVM 仅由预编译器使用。如果您可以显示以某种方式依赖于 IKVM 的代码,那么我需要尽快修复它。但我认为您已经从预编译器中引用了 dll。不要那样做;这是不同的。
  • 引用错误的dll是什么意思?我应该参考什么?顺便说一句,我在我的程序中删除了对 IKVM 的引用,仍然得到错误“不支持指定的方法”。
  • @La 我假设您正在使用 gcode 包。其中包含诸如 full/net30 (这将是一个很好的默认值)和其他文件夹。请参阅“我需要哪些文件.txt”
  • Google-code aka Code.Google.com - 可能是您在其中下载了一个包含大量文件夹的 zip 文件。文本文件位于 zip 的根目录中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-10
  • 1970-01-01
  • 2014-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多