【问题标题】:Binary serialization without serializable attribute没有可序列化属性的二进制序列化
【发布时间】:2017-01-08 21:51:42
【问题描述】:

我想对我的对象进行序列化并使用BinaryFormatter 类。

public static byte[] BinarySerialize(IMessage message)
{
    using (var stream = new MemoryStream())
    {
        var formatter = new BinaryFormatter();

        formatter.Serialize(stream, message);

        return stream.ToArray();
    }
}

但是当我运行代码时,会引发异常。

SerializationException:对象未标记为可序列化。

我认为这个异常是 BinaryFormatter 抛出的。

我不想将我的对象标记为[Serializable]。或者我的图书馆用户可能会忘记将自己的消息标记为[Serializable]

有没有其他方法可以在不使用 [Serializable] 属性的情况下对我的对象进行二进制序列化?

【问题讨论】:

  • 检查 Protobuf,不需要 Serializable 属性
  • var 结果 = BinarySerialize(JsonConvert.SerializeObject(message));
  • var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message));
  • 经过两个序列化阶段?
  • 如何反序列化?二进制反序列化返回命名空间和类信息的原始对象。但是 Json 反序列化只返回像这样的对象 {"id": "000"}

标签: c# .net serialization


【解决方案1】:

由于 [Serializable] 属性无法在运行时添加,如果您想坚持 .Net 内置的序列化,则没有选项。

你可以

  1. 在 IMessage 中使用 ISerializable 接口,以便用户必须在其实现中实现序列化
  2. 使用外部库,例如:http://sharpserializer.codeplex.com/ 顺便说一句,他们已经搬到了 GitHub。见:https://github.com/polenter/SharpSerializer

    public static byte[] BinarySerialize(IMessage message)
    {
        using (var stream = new MemoryStream())
        {
            var serializer = new SharpSerializer(true);
    
            serializer.Serialize(message, stream );
    
            return stream.ToArray();
        }
    }   
    
  3. 使用 JSON 序列化

【讨论】:

  • Json会是文本序列化,OP需要二进制序列化,可能不适合
  • 是的.. 那么最简单的方法就是使用Sharpserializer,对他的代码做最少的改动
【解决方案2】:

除了关于 3rd 方库的其他答案之外,根据您的需要,您可以选择使用 XmlSerializer。 (最好使用不需要SerializeableAttributeJSON serializer。)

这些序列化程序不需要[Serializeable]。但是,XmlSerializer 也不允许接口序列化。如果你擅长具体类型,它就可以工作。 Compare serialization options

例如

void Main()
{
    var serialized = Test.BinarySerialize(new SomeImpl(11,"Hello Wurld"));
}

public class Test
{
    public static string BinarySerialize(SomeImpl message)
    {
        using (var stream = new StringWriter())
        {
            var formatter = new XmlSerializer(typeof(SomeImpl));

            formatter.Serialize(stream, message);

            return stream.ToString().Dump();
        }
    }

}

public class SomeImpl
{
    public int MyProperty { get;set;}
    public string MyString { get;set; }

    public SomeImpl() {}

    public SomeImpl(int myProperty, String myString)
    {
        MyProperty = myProperty;
        MyString = myString;
    }
}

【讨论】:

    【解决方案3】:

    为避免 Net4x 内置需要 [Serializable] 属性的序列化,请在 netcore 3.1+ 或 Net5 中使用 Newtonsoft.Json 或 System.Text.Json

     
    string json= JsonConvert.SerializeObject(message); 
    
    //or System.Text.Json in netcore 3.1+
    string json=  System.Text.Json. JsonSerializer.Serialize(message);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-04
      • 1970-01-01
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      相关资源
      最近更新 更多