我又一个类FileInfo保存文件信息的,大致如下
[Serializable]
public class FileInfo : ISerializable
{
    public string FileName
    {
        get;
        set;
    }    private byte[] _body;
    public byte[] Body
    {
        get
        {
            if (_body == null)
            {
                _body = System.IO.File.ReadAllBytes(Source);
            }            return _body;
        }
    }    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("FileName", FileName + "@@@");  //@@@用于验证这行是否被执行
        info.AddValue("Body", Convert.ToBase64String(Body));
    }
}这个类有两个属性,文件名FileName和文件体Body,为了存放二进制文件Body的类型是byte[]。
我的目的是可以通过WebServices把文件发布出去,其中byte[]的Body不能被自动序列化,所以我实现了GetObjectData,其中把Body做了下Base64。然而调用webservices得到的结果只有FileName一个值并无Body,并且FileName后面没有我有意加的“@@@”(见前面的代码),说明GetObjectData并未被执行我又用XmlSerializer方式序列化,也是得不到Body,也没有“@@@”
用BinaryFormatter方式序列化,这次得到了Body,并且有“@@@”,说明执行了GetObjectData()
我想知道为什么会有这样的差异?烦劳指点,感激涕零!

解决方案 »

  1.   

    自己往前推进了点1、Body没有被序列化是因为它是只读的,加了个get就好了。
    2、还是只有BinaryFormatter能够调用GetObjectData,但是发现webService会自动对byte[]属性进行base64编码,大出意外。
    现在我把对ISerializable 的继承取消了,GetObjectData自然也取消,完全靠webService自动的序列化我的对象。
    这中间还是有一些不解,放后面研究明白了再贴出来
      

  2.   

    XML序列化是个跨平台的国际标准,byte[]如何序列化的规则是标准的,用不着自定义。使用XML、Json等方式,根本用不着ISerializable这个接口,如果要控制序列化过程,它们各自有几个Attribute用于控制。
      

  3.   

    可能是这一部分的msdn文档比较老的原因,文字写错了。msdn上第一句话:“任何可以序列化的类都必须用 SerializableAttribute 进行标记”就是错误的。
      

  4.   

    补充一点点吧。二进制序列化实际上是针field的,包括private的field。xml和json序列化是针对public的field和property的。如果自己需要定义协议,建议使用json而不要使用xml。xml序列化结果比较长,特别是往往会有额外的命名空间和其它属性,造成反序列化失败,不如json精简和方便。特别是,xml序列化/反序列化要性能比json差许多。json唯一地缺点是对byte[]的序列化性能很差(它按照普通数组序列化而没有特别处理)。所以应该定义一个string类型的属性来表达byte[]的base64编码,然后把原来的属性用ScriptIgnoreAttribute标记来声明。