可靠的集合(队列)值存储一些复杂的类型SomeUnit
.
我已经将它标记为[DataContract]
并且它是成员,[DataMember]
并且[KnownType(typeof(SomeUnit))]
还在其上添加了属性.
看起来现在SomeUnit序列化,但随后抛出反序列化异常:
元素'urn:ServiceFabric.Communication:item'包含映射到名称' http://schemas.datacontract.org/2004/07/RP.Core:SomeUnit ' 的类型的数据.反序列化器不知道映射到此名称的任何类型.如果使用DataContractSerializer或将与"SomeUnit"对应的类型添加到已知类型列表中,请考虑使用DataContractResolver - 例如,使用KnownTypeAttribute属性或将其添加到传递给序列化程序的已知类型列表中.
我该如何解决?
由于您没有显示任何代码,我们只能猜测导致此问题的原因.
如果您将使用具有通用项类型的可靠队列(例如基类),则会发生此问题SomeUnit
.
// Using reliable collection with a base item type IReliableQueuemyQueue = ...; // Store derived item in the queue SomeUnit myData = ...; // SomeUnit inherit from BaseClass await myQueue.EnqueueAsync(txn, myData); // OK to store but won't deserialize!
该队列的反序列化器将知道如何解析,BaseClass
但它不会隐式地知道您的派生类SomeUnit
.
您可以通过KnownTypeAttribute
在基类上应用a来解决这个问题,从而明确声明反序列化程序应该知道的派生类.
[DataContract] [KnownType(typeof(SomeUnit))] public class BaseClass { ... } [DataContract] public class SomeUnit : BaseClass { ... }
在接口类型上应用[KnownType]是不可能的.但是,有一些选项可以支持这个:
使用包装器合约声明已知类型.
[DataContract] [KnownType(typeof(SomeUnit))] public class Wrapper { [DataMember] public IUnit Value { get; set; } } [DataContract] public class SomeUnit : IUnit { ... }
为DataContractSerializer构造函数指定已知类型.
但是,这需要您告诉服务结构使用您的自定义序列化程序.
如此处所述,在配置文件(app.config)中指定已知类型.