runtime: SerializationException: Type 'System.Collections.Hashtable+SyncHashtable' in Assembly 'System.Runtime.Extensions, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable

I have ported a number of class libraries from .NET Framework 4.5 to .NET Standard 2.0. Using these libraries from a .NET Framework 4.8 console application works fine. However referencing the libraries from a .NET Core 2.2 console app, results in the following exception:

SerializationException: Type 'System.Collections.Hashtable+SyncHashtable' in Assembly 'System.Runtime.Extensions, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable

with stack trace

   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.CheckSerializable(Type t)
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.ParseObject(ParseRecord pr)
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Parse(ParseRecord pr)
   at System.Runtime.Serialization.Formatters.Binary.BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum binaryHeaderEnum)
   at System.Runtime.Serialization.Formatters.Binary.BinaryParser.Run()
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(BinaryParser serParser, Boolean fCheck)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, Boolean check)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)

My inner most calling code to the framework that’s failing is this:

public static object Deserialize(BinaryReader binaryReader)
{
    BinaryReader binaryReader = new BinaryReader(inStream);
    BinaryFormatter binaryFormatter = new BinaryFormatter();
    return binaryFormatter.Deserialize(binaryReader.BaseStream);
}

Thanks in advance.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 16 (11 by maintainers)

Most upvoted comments

@ershadnozari the above were notes to myself 😃

In .NET Core fewer types are binary serializable than in .NET Framework. This is by design because serialization based on BinaryFormatter has historically been fragile and prone to security problems. SyncHashtable is not currently serializable. However we should probably make it so. Meantime you need to avoid serializing it. This may mean using Hashtable and manually locking instead of using SyncHashtable. Or possibly (advanced) using the extension mechanisms of BinaryFormatter to work around the problem.

This is arguably an oversight, as it is really part of Hashtable

It does not look like an oversight to me. All internal parts of Hashtable (Enumerator, KeyCollection, ValueCollection) were serialiable in .NET Framework. None of these parts are serialiable in .NET Core. Same for Dictionary and other collections.

I’m thinking we should at least mark SyncHashtable with [Serialized]

That alone is not sufficient to make SyncHashtable binary serialize correctly. It would also need to implement ISerializable interface because of it inherits from Hashtable that implements ISerializable interface. And there is a good change that there is more to it because of binary serialization is always full of surprises. You won’t really know until you add tests.

Aren’t the set of API’s, in .NET Standard library, the same in both cases?

.NET Standard guarantees that the APIs are there, but it does not guarantee that they behave exactly the same.

@jkotas I’m thinking we should at least mark SyncHashtable with [Serialized] as it has zero fields beyond Hashtable and apparently it’s referenced (if not binary serialized) in 10% of APIcompat samples. Perhaps also some of the others (although they do have a sync root field as well, it would be type literal object)