我有一个实现以下DataMember的服务:
[DataMember]
public Dictionary<string, List<IOptionQueryResult>> QueryResultItems { get; set; }
我有一个继承自IOptionQueryResult的类“OptionQuerySingleResult”。现在,我明白我需要让OptionQueryResult类型为服务“已知”,因此尝试以各种方式添加KnownType:
[KnownType(typeof(Dictionary<string, OptionQuerySingleResult[]>))]
[KnownType(typeof(Dictionary<string, List<OptionQuerySingleResult>>))]
[KnownType(typeof(OptionQuerySingleResult)]
然而,这些方法都没有起作用,而且在客户端,我要么反序列化失败,要么服务器只是中止了请求,导致连接中止错误。
有没有人知道让这个工作的正确方法是什么? 我想补充一点,如果我将QueryResultItems定义更改为使用具体类型而不是接口,那么一切都运行正常。
谢谢,
汤姆
编辑: 我得到的例外是:
第1行位置524出错。元素“http://schemas.microsoft.com/2003/10/Serialization/Arrays:anyType”包含映射到名称':OptionQuerySingleResult'的类型的数据。反序列化器不知道映射到此名称的任何类型。考虑使用DataContractResolver或将与'OptionQuerySingleResult'对应的类型添加到已知类型列表中 - 例如,通过使用KnownTypeAttribute属性或将其添加到传递给DataContractSerializer的已知类型列表。
但是,当我查看svcutil生成的客户端代理时,其中明确定义了“OptionQuerySingleResult”:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="OptionQuerySingleResult", Namespace="")]
[System.SerializableAttribute()]
public partial class OptionQuerySingleResult : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged
答案 0 :(得分:1)
我想你会用:
[KnownType(typeof(OptionQuerySingleResult)]
但是你还需要在OptionQuerySingleResult类上使用[DataContract(Name = "OptionQuerySingleResult")]
。
我认为这也依赖于SVCUTIL.EXE util生成的客户端代理类。
答案 1 :(得分:0)
您只需将以下属性添加到datacontract类。
[DataMember]
public object UsedForKnownTypeSerializationObject;
现在生成的代理包含您在datacontract上设置的Knowtypes。 我有同样的问题,这是我提出的唯一解决方案。 如果你没有在Object类型的属性上为你的DataContract类, 生成的代理不包含声明的知识类型
例如:
[DataContract]
[KnownType(typeof(List<String>))]
public class Foo
{
[DataMember]
public String FooName { get; set; }
[DataMember]
public IDictionary<String, Object> Inputs { get; set; }
[DataMember]
private Object UsedForKnownTypeSerializationObject{ get; set; }
}
它不是那么漂亮,因为你最终得到一个没有任何虚拟属性 功能实现。但是,我再没有其他解决方案。