将对象序列化为文件时的C#最佳实践

gil*_*lyb 14 c# serialization

我正在构建一个小应用程序,需要将对象保存到文件中以保存用户数据.关于我对此文件的序列化,我有两个问题:

  1. 我正在创建的对象有一些公共属性和一个事件.我将[Serializable]属性添加到我的对象,然后意识到我无法序列化其中包含事件的对象.然后我发现我可以在我的事件之上添加一个属性[field:NonSerialized],它会起作用.这是最好的方法吗,或者我应该尝试构建我的Serializable对象而没有任何事件?

  2. 我正在序列化的对象保存了一些关于应用程序的用户设置.这些设置不够灵敏,无法在文件中加密它们,但我仍然不希望它们在不打开我的应用程序的情况下手动篡改.当我使用普通BinaryFormatter对象将我的对象序列化为文件时,通过该Serialize()方法,我在文件中看到.net对象类型的可读名称,我将其保存到.有没有办法让某人对此进行逆向工程,看看在不使用我的程序的情况下保存了什么?有没有办法让某人建立一个小应用程序,并找出如何DeSerialize此文件中的信息?如果是这样,我将如何隐藏此文件中的信息?

在这种情况下,当将对象序列化为文件时,是否还有其他提示/建议/最佳实践?

提前致谢!

GvS*_*GvS 11

如果对象实现了ISerializable接口,则可以自己控制存储/序列化的所有数据,并可以控制反序列化.

如果您的项目及时发展,这一点非常重要.因为您可能会删除某些属性,添加其他属性或更改行为.

我总是在序列化包中添加一个版本.这样我知道对象存储时的版本是什么,因此我知道如何反序列化它.

[Serializable]
class Example : ISerializable {
   private static const int VERSION = 3;

   public Example(SerializationInfo info, StreamingContext context) {
      var version = info.GetInt32("Example_Version", VERSION);
      if (version == 0) {
         // Restore properties for version 0
      }
      if (version == 1) {
         // ....
      }
   }

   void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
       info.AddValue("Example_Version", VERSION);
       // Your data here
   }

}
Run Code Online (Sandbox Code Playgroud)

如果您不加密,则可以非常轻松地"读取"您的数据.很容易意味着您可能需要投入几个小时.如果您存储的数据值几天,这意味着它很容易,如果它只值几分钟很难.如果你明白了.

加密数据的一种非常简单的方法是通过ProtectedData类使用Windows DPAPI .