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

时间:2014-07-25 08:12:42

标签: c# serialization deserialization

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

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用户的对象反序列化为current用户?

当我尝试反序列化时,我会遇到异常: {"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;
}

2 个答案:

答案 0 :(得分:5)

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

二进制对象序列化到数据库中是非常糟糕的。数据库是长寿和可查询的。你是一举否定的:你的长期数据可以通过你现在拥有的非常具体的代码来反序列化(20年后,有人必须运行C#v.4.5来对今天存储的对象进行去序列化)和二进制序列化对象对于数据库而言,它只是一个不透明的blob,不可思议且无法搜索。

不要这样做。

答案 1 :(得分:0)

我假设存在一些将二进制数据存储在数据库中的有效情况。例如,在我们的商业产品中,数据库用于内部存储数据,因此我们使用二进制序列化形式使其有意不可查询和不可搜索。我们将索引关键字列与二进制数据列一起进行查找,但除此之外,该数据无法识别。

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

我们使用version tolerant serialization (VTS)解决了更新后的代码问题,但不确定这对名称空间已更改的原始帖子有帮助。