【问题标题】:How much does a class/object have to change in order for binary-deserialization to fail为了使二进制反序列化失败,类/对象必须更改多少
【发布时间】:2015-07-26 06:08:06
【问题描述】:

我们有一个解决方案,我们将一个相当大/复杂的 C# 对象作为二进制数据存储在我们的数据库中。我担心的是,当对这个类进行更改时,我们冒着保存到数据库的数据在代码更改后反序列化失败的风险。

这是我们用来序列化对象的代码:

    public static byte[] SerializeObject(object toBeSerialized)
    {
        var stream = new MemoryStream();
        var serializer = new BinaryFormatter();
        serializer.Serialize(stream, toBeSerialized);
        stream.Position = 0;
        return stream.ToArray();
    }

这是我们的反序列化方法:

    public static T DeserializeObject<T>(byte[] toBeDeserialized)
    {
        using (var input = new MemoryStream(toBeDeserialized))
        {
            var formatter = new BinaryFormatter();
            input.Seek(0, SeekOrigin.Begin);
            return (T) formatter.Deserialize(input);
        }
    }

我的问题是,为了使旧对象的反序列化失败,必须改变什么/改变多少?

【问题讨论】:

  • 将数据存储为 blob 不是一个好主意。比版本控制更糟糕的是,无法查询数据。您不妨将它们保存到二进制文件中。您试图通过使用 BLOB 而不是表字段来解决什么问题?为什么不创建适当的模式?为什么不使用稀疏列、xml 字段甚至是用户定义的类型,如 Oracle 中的类或 SQL 中的 CLR 类型?
  • @PanagiotisKanavos - 我们很清楚将数据存储为 blob 并不是理想的解决方案,但是鉴于这一特殊要求的时间线,这是让用户返回到确切状态的唯一方法应用程序,他们没有进行大修就离开了它。我们不会以这种方式存储订单或我们需要查询的任何内容,这只是为了让用户可以保存他们离开的地方。

标签: c# .net binary-serialization binary-deserialization


【解决方案1】:

对类的数据结构(属性和字段)的任何更改都会在尝试反序列化数据时给您带来问题。

我确信更改方法的定义不会给您带来任何问题,添加或删除方法同样没问题。

编辑:我已经对我开发的类似系统进行了一些测试,我发现您可以添加新的属性和字段并仍然反序列化旧对象。在我看来,您唯一遇到的问题是如果您删除、重命名或更改现有字段和属性的类型。

Related Question

【讨论】:

    【解决方案2】:

    始终保持序列化版本容差,在this 文章中你可以找到一些建议

    您还可以在下面找到一些破坏序列化/反序列化的情况

    • 删除序列化字段时

    • 当您将 NonSerializedAttribute 属性应用到字段时,如果该属性未应用于先前版本中的字段。

    • 当您更改序列化字段的名称或类型时。

    • 添加新的序列化字段时,没有 OptionalFieldAttribute 属性。

    • 从字段中删除 NonSerializedAttribute 属性(在以前的版本中不可序列化)时,没有 OptionalFieldAttribute 属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-22
      • 2012-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多