Reliable Collection (Queue) values store some complex type SomeUnit
.
I've marked it as [DataContract]
and it's members as [DataMember]
and added [KnownType(typeof(SomeUnit))]
attribute on top of it also.
Looks like now SomeUnit serializes, but then deserialize exception is thrown:
Element 'urn:ServiceFabric.Communication:item' contains data from a type that maps to the name 'http://schemas.datacontract.org/2004/07/RP.Core:SomeUnit'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver if you are using DataContractSerializer or add the type corresponding to 'SomeUnit' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to the serializer.
How can I solve it?
Since you are not showing any code we can only guess what's causing this.
This problem would occur if you would use a reliable queue with a generalized item type, for example a base class of SomeUnit
.
// Using reliable collection with a base item type
IReliableQueue<BaseClass> myQueue = ...;
// Store derived item in the queue
SomeUnit myData = ...; // SomeUnit inherit from BaseClass
await myQueue.EnqueueAsync(txn, myData); // OK to store but won't deserialize!
The deserializer for that queue would know how to parse BaseClass
but it won't be implicitly aware of your derived class SomeUnit
.
You can fix that by applying a KnownTypeAttribute
on the base class, thereby explicitly declaring the derived classes that the deserializer shall be aware of.
[DataContract]
[KnownType(typeof(SomeUnit))]
public class BaseClass
{
...
}
[DataContract]
public class SomeUnit : BaseClass
{
...
}
It's not possible to apply [KnownType] on an interface type. There are, however, some options for supporting this:
Use a wrapper contract to declare known type(s).
[DataContract]
[KnownType(typeof(SomeUnit))]
public class Wrapper
{
[DataMember]
public IUnit Value { get; set; }
}
[DataContract]
public class SomeUnit : IUnit
{
...
}
Specify known types to the DataContractSerializer constructor.
This will, however, require that you tell service fabric to use your custom serializer.
Specify known types in a configuration file (app.config) as described here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With