1

I am trying to serialize/deserialize my custom class which contains hashtable property using protobuf-net v2.

    [ProtoContract]
    public class MyClass
    {
        [ProtoMember(1)]
        public Hashtable MyHashTable { get; set; }
   }

When I call Serializer.Serialize(...) exception appears: No serializer defined for type: System.Collections.Hashtable

I try to modify:

    [ProtoContract]
    public class MyClass
    {
        [ProtoMember(1, DynamicType = true)]
        public Hashtable MyHashTable { get; set; }
   }

But I have another exception: Type is not expected, and no contract can be inferred: System.Collections.DictionaryEntry

Maybe someone know a way how I can serialize hashtable?

  • Do you want to serialized the objects stored in the hash table or the hash table itself? – David Schwartz May 16 '12 at 09:41
  • It will be nice to store hash table and use it after deserialization, but if there a way to store objects from hash table only - it's Ok. – Artem Taradeiko May 16 '12 at 09:56
  • 2
    protobuf-net does not currently directly support this scenario, and I'm not sure it is one that I'm in a hurry to support. In a contract-based serializer, the *intention* is that you know the shape of the data ahead of time. For example, a `Dictionary` would work *fine*, as it is very clear what that means and what the data will contain. – Marc Gravell May 16 '12 at 09:58
  • You can try this: http://www.techrepublic.com/blog/howdoi/how-do-i-serialize-a-hash-table-in-c-when-the-application-requires-it/143 – eyossi May 16 '12 at 10:01
  • eyossi , I need to use protobuf becuase performance is very important for me. @Marc Gravell♦ thanks, I know about this solution, but I was hoping that I can find better solution. – Artem Taradeiko May 16 '12 at 10:13
  • Without more context on what the contents **are likely to be**, it is very hard for me to answer that. `Hashtable` is such a vague thing. *What are the contents?* – Marc Gravell May 16 '12 at 10:14
  • Sorry, I don't understand your question. You ask what I want to store in hash table or what HashTable type contains? – Artem Taradeiko May 16 '12 at 10:36
  • Hashtable is so broad what you can store. 1 record might be a string, another a Custom Object, another an integer. You need to look at if you can make something more specific. `DynamicType` is for when you change the serializable object on your class being stored at runtime (but the attached object still needs to be serializable) – Paul Farry May 17 '12 at 00:09

1 Answers1

1

Thanks to all who helped me. Here is my solution. I know that this is not best way, but maybe for someone it acceptable.

    [ProtoContract]
    public class HashtableTestClass
    {
        private string inputParametersBase64 = string.Empty;
        private Hashtable myHashTable;

        public Hashtable MyHashtable
        {
            get { return myHashTable; }
            set { myHashTable = value; }
        }

        [ProtoMember(1)]
        public string InputParametersBase64
        {
            get
            {
                if (myHashTable == null)
                    return string.Empty;

                return HashtableToBase64(myHashTable);
            }
            set
            {
                inputParametersBase64 = value;
                if (!string.IsNullOrEmpty(inputParametersBase64))
                {
                    try
                    {
                        myHashTable = Base64ToHashtable(inputParametersBase64);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                    }
                }
            }
        }

        public static Hashtable Base64ToHashtable(string s)
        {
            MemoryStream stream = new MemoryStream(Convert.FromBase64String(s), false);
            IFormatter formatter = new BinaryFormatter();

            return (Hashtable)formatter.Deserialize(stream);
        }

        public static string HashtableToBase64(Hashtable hashtable)
        {
            IFormatter formatter = new BinaryFormatter();
            MemoryStream stream = new MemoryStream();
            formatter.Serialize(stream, hashtable);
            stream.Close();
            return Convert.ToBase64String(stream.ToArray());
        }
    }