C#中没有属性的序列化/反序列化

时间:2018-06-14 11:02:14

标签: c# serialization protobuf-net binary-serialization

我有很多类,包括对象层次结构和接口的常规设计,基类等来自我无法修改任何代码的项目。我的项目中有另一个有效负载类,它使用组合来封装来自其他类的信息,并在有效负载类中包含属性,其类型是来自另一个项目的类。

现在我需要能够创建包含那些其他类的实例的有效载荷类的实例,并将其序列化为Base64字符串以进行传输。

问题是因为我无法触及其他类的代码,我无法添加序列化属性(对于.NET二进制格式化程序/ protobuf-net)。我也试图在没有属性的情况下使用protobuf-net,但由于对象层次结构太深,所以创建它似乎太复杂了。

有人可以告诉我在不修改现有代码的情况下继续使用序列化/反序列化部分的更好选择。

说明要求的示例代码如下所示:

void Main()
{
    var b = new B();
    b.SetStatus("This is B");

    var c = new C { Name = "C", Value = 100};

    var payload = new Payload(b, c);

    var serializedData = SerializeToString<Payload>(payload);

    serializedData.Dump();
}

private static TData DeserializeFromString<TData>(string settings)
{
    byte[] b = Convert.FromBase64String(settings);
    using (var stream = new MemoryStream(b))
    {
        var formatter = new BinaryFormatter();
        stream.Seek(0, SeekOrigin.Begin);
        return (TData)formatter.Deserialize(stream);
    }
}

private static string SerializeToString<TData>(TData settings)
{
    using (var stream = new MemoryStream())
    {
        var formatter = new BinaryFormatter();
        formatter.Serialize(stream, settings);
        stream.Flush();
        stream.Position = 0;
        return Convert.ToBase64String(stream.ToArray());
    }
}

public class A
{
    public string Id { get; set; }
    public string StatusMsg {get;protected set;}
    public virtual void SetStatus(string msg)
    {
        StatusMsg = msg;
    }
}

public class B : A
{
    public B()
    {
        Id = new Guid().ToString();
    }

    public override void SetStatus(string msg)
    {
        base.SetStatus(msg);
    }
}

public class C
{
    public string Name
    {
        get;
        set;
    }

    public Int32 Value
    {
        get;
        set;
    }
}

public class Payload
{
    public B PropertyB { get; set; }
    public C PropertyC { get; set; }

    public Payload(B b, C c)
    {
        this.PropertyB = b;
        this.PropertyC = c;
    }
}

2 个答案:

答案 0 :(得分:0)

我不明白为什么protobuf不起作用,但如果你不介意的话,你可以手动进行序列化。

在这种情况下,创建一个BinaryWriter,然后使用BinaryReader编写所需的所有内容,以便能够将其反序列化。通过这种方式,您将获得一个非常紧凑的表示,为您的特定需求量身定制,也​​非常快。但它还有一些工作要做。通用序列化可能冗长而缓慢,但在任何情况下几乎都是首选。

但我仍然不明白为什么使用任何现有的无属性序列化方法都行不通。您应该首先真正理解为什么它不能用于例如protobuf或JSON.NET。你提到了#34;太深的层次结构&#34;。那有多深?

答案 1 :(得分:0)

如果不添加配置属性,您可以选择以下几个选项:

  • 使用不关心的序列化:如果幸运,XmlSerializer或Json.NET可能会起作用
  • 接受protobuf-net或其他之一的运行时配置工作;它可能没有你想象的那么多(哎呀,给我发一封真正代码的电子邮件,我也许可以做到)。
  • 完全手动编写序列化
  • 编写一个DTO图层 - 一个具有属性等的基本模型,可以很好地处理您选择的序列化程序 - 并编写代码以在两个模型之间进行映射,或者使用像auto-mapper这样的工具

就个人而言,当序列化配置变得棘手时,我的默认选项是“编写DTO模型”。