0

I'm trying to parse a MessagePack message. When I declare the field in question as a Dictionary<string, Package> everything works fine and the message is unpacked as expected. However, when I instead declare the field in question as a custom dictionary implementation, PackageDictionary, the MsgPack library tries to deserialize it as an array. I have defined PackageDictionary as an IDictionary<string, Package>. What is going on? Shouldn't the MsgPack library interpret all IDictionary implementations as a dictionary and not an array? What am I doing wrong? Do I need to use a attribute to mark that the field should be deserialized as a dictionary?

Here's an example of what i'm trying to do:

[DataContract]
public class PackagesMessage
{
    [DataMemeber]
    public PackageDictionary Packages { get; set; }
}

public class PackageDictionary : IDictionary<string, Package> { ... }

This is where i get an error message saying "Unpacker is not in the array header at position..."

If instead I switch the Packages type to Dictionary like so:

[DataContract]
public class PackagesMessage
{
    [DataMember]
    public Dictionary<string, Package>() Packages { get; set; }
}

Everything works fine and the message is correctly deserialized. Any ideas?

Any help would be greatly appreciated.

Update

I found a work around, not ideal, but I am able to parse the field as PackageDictionary type if I change the property to IDictionary<string, Package>, then set the default collections serializer for IDictionary<string, Package> to PackageDictionary. This works at the moment because all IDictionary<string, Package> fields should be interpretted as a PackageDictionary type but I could see this being a problem if I needed a more common IDictionary like IDictionary<string, string> and if depending on the field the implementations would need to be different. I'm confused on how setting the serialization context to use PackageDictionary serializer as the default for IDictionary works but it can't figure out that is should use the same serializer when PackageDictionary is the actual type of the property. Any thoughts?

CSCoder
  • 154
  • 1
  • 15
  • Well then use a Dictionary for the DataContract class. After deserialization map it to the class you want to work with – Sir Rufo May 04 '17 at 18:47
  • And you can check if MessagePack is looking for ISerializable and if then implement that interface on your custom class – Sir Rufo May 04 '17 at 18:52
  • @SirRufo I could deserialize it into a seperate class but the class is actually a lot bigger than what I've shown here. Everything deserializes fine except this one custom dictionary implementation. I don't really what to have 2 classes that are exactly the same except for this one property. As for ISerializable, I don't think MessagePack uses this interface as far as i can tell. – CSCoder May 04 '17 at 18:57
  • Following Single-Responsibility-Principle you will have 2 classes, although they seem to be equal, but they are not. One is for the Persistence-Layer and the other for the Application-Layer. – Sir Rufo May 04 '17 at 21:06

0 Answers0