System.InvalidCastException "Object must implement IConvertible." 使用 BinaryFormatter 反序列化字典时


[Serializable]
public class CustomFields : MyObject, ICustomFields // MyObject is marked as ISerializable
{
private IDictionary<string, string> _customFieldDictionary;
public CustomFields( ) {
this._customFieldDictionary = new Dictionary<string, string>( );
}
protected CustomFields( SerializationInfo info, StreamingContext context )
: base( info, context )
{
if( info == null )
throw new System.ArgumentNullException( "info" );
// Following line throws
this.CustomFieldDictionary = ( Dictionary<string, string> ) info.GetValue( "CustomFieldDictionary", typeof( Dictionary<string, string> ) );
}
[SecurityPermission( SecurityAction.LinkDemand,
Flags = SecurityPermissionFlag.SerializationFormatter )]
public override void GetObjectData( SerializationInfo info, StreamingContext context )
{
if( info == null )
throw new ArgumentNullException( "info" );
base.GetObjectData( info, context );
info.AddValue( "CustomFieldDictionary", this.CustomFieldDictionary, typeof( Dictionary<string, string> ) );
}
public virtual IDictionary<string, string> CustomFieldDictionary
{
get { return this._customFieldDictionary; }
set { this._customFieldDictionary = value; }
}
}

此类由另一个可序列化类引用。

[Serializable]
public class UserOfCustomFields : MyObject, IUserOfCustomFields {
public UserOfCustomFields( ) {
this.CustomFields = new CustomFields( );
}
protected UserOfCustomFields( SerializationInfo info, StreamingContext context ) : base(info, context)
{
if( info == null )
throw new System.ArgumentNullException( "info" );
this.CustomFields = ( CustomFields ) info.GetValue( "CustomFields", typeof( CustomFields ) );
}
[SecurityPermission(SecurityAction.LinkDemand,
Flags = SecurityPermissionFlag.SerializationFormatter)]
public override void GetObjectData( SerializationInfo info, StreamingContext context )
{
if( info == null )
throw new ArgumentNullException( "info" );
base.GetObjectData( info, context );
info.AddValue( "CustomFields", this.CustomFields, typeof( CustomFields ) );
}
public virtual ICustomFields CustomFields { get; set; }
}

下面是调用序列化/反序列化代码的代码:

public bool SaveObjects( IEnumerable<IMyObject> objects ) {
// If we have null objects fail
if ( objects == null ) { return false; }
var local_objects = objects.ToList( );
var new_list = new List< IDBObject< Guid > >( );
foreach ( var obj in local_objects ) {
var clone = this.DeepCopy( obj );
new_list.Add( clone );
}
return true;
}

实际的序列化/反序列化发生在这里:

public virtual T DeepCopy<T>( T obj )
{
if( !obj.GetType( ).IsSerializable )
{
throw new Exception( "The source object must be serializable" );
}
if( Object.ReferenceEquals( obj, null ) )
{
throw new Exception( "The source object must not be null" );
}
T result = default( T );
using( var memoryStream = new MemoryStream( ) )
{
var formatter = new BinaryFormatter( );
formatter.Serialize( memoryStream, obj );
memoryStream.Seek( 0, SeekOrigin.Begin );
result = ( T ) formatter.Deserialize( memoryStream );
memoryStream.Close( );
}
return result;
}

如标题中所述,我在反序列化时得到System.InvalidCastException"对象必须实现IConvertable"。字典是特例吗?我对任何其他类型都没有问题(到目前为止(。

事实证明,由于我使用的是 NHibernate,它注入了它自己的集合实现。为了使这项工作,我必须在序列化/反序列化中使用接口 IDictionary:

protected CustomFields( SerializationInfo info, StreamingContext context )
: base( info, context )
{
if( info == null )
throw new ArgumentNullException( "info" );
this.CustomFieldDictionary = ( IDictionary<string, string> ) info.GetValue( "CustomFieldDictionary", typeof( IDictionary<string, string> ) );
}
[SecurityPermission( SecurityAction.LinkDemand,
Flags = SecurityPermissionFlag.SerializationFormatter )]
public override void GetObjectData( SerializationInfo info, StreamingContext context )
{
if( info == null )
throw new ArgumentNullException( "info" );
base.GetObjectData( info, context );
// Following line throws
info.AddValue( "CustomFieldDictionary", this.CustomFieldDictionary, typeof( IDictionary<string, string> ) );
}

相关内容

  • 没有找到相关文章

最新更新