如何使用BinaryFormatter (c#)将一个类反序列化为不同的类(在新的命名空间中)

本文关键字:命名空间 一个 BinaryFormatter 何使用 反序列化 | 更新日期: 2023-09-27 18:14:39

我有一个属于Authentication命名空间的类User,如下所示:

namespace Authentication {
    public class User 
    {
       public string Name {get;set;}    
    }
}

我使用BinaryFormatter将User类的对象序列化为byte[],并将其存储在数据库中。

User usr = new User();
usr.Name = "myself";
var usrValue = convertObjectToByteArr(usr);
//then store usrValue into db.

一段时间后,类User有了新的属性,并移动到新的命名空间:Authentication.Organization

namespace Authentication.Organization{
    public class User 
    {
        public string Name {get;set;}
        public int Age {get;set;}
    }
}

我的问题:如何将previous User的对象反序列化为current User ?

当我试图反序列化它时,我会点击exception: {"Unable to load type Authentication.User required for deserialization."} :

byte[] prevUsrValue= (byte[])helper.getPreviousUserValue();//read from database
User previousUser = convertByteArrToObject(prevUsrValue) as User;

供参考,我正在使用这些方法来序列化和反序列化:

//serialization
public static byte[] convertObjectToByteArr(object o)
{
    if (o != null)
    {
        System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
        System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        binaryFormatter.Serialize(memoryStream, o);
        return memoryStream.ToArray();
    }
    return null;
}
//de-serialization
public static object convertByteArrToObject(byte[] b)
{
    if (b != null && b.Length > 0)
    {
        System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(b);
        System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        memoryStream.Position = 0;
        return binaryFormatter.Deserialize(memoryStream);
    }
    return null;
}

如何使用BinaryFormatter (c#)将一个类反序列化为不同的类(在新的命名空间中)

不要在数据库中存储二进制序列化对象。使用你选择的ORM (EF, Linq2SQL, NHibernate等)将用户作为属性序列化到表中。

二进制对象序列化到数据库中是非常糟糕的。数据库是长期存在的,并且是可查询的。你一下子否定了这两点:你的长期数据只能由你现在拥有的非常特定的代码来反序列化(20年后有人将不得不运行c# v. 4.5来对你今天存储的对象进行反序列化),而二进制序列化的对象对数据库来说只不过是一个不透明的blob,不可查询和不可搜索。

别这么做

我认为在数据库中存储二进制数据有一些有效的情况。例如,在我们的商业产品中,数据库用于内部存储数据,因此我们有意使用二进制序列化形式使其不可查询和不可搜索。我们在二进制数据列中包含一个索引键列,用于查找,但除此之外,数据是不可识别的。

与为对象中的每个字段创建一列相比,二进制序列化的数据占用的存储空间更少。

我们使用版本容忍序列化(VTS)来解决更新后的代码问题,但不确定这对名称空间发生变化的原始帖子有帮助。