我想知道如何在WCF中配置已知类型。例如,我有一个 Person 类和一个 Employee 类。 员工类是 Person 类的子类。这两个类都标有[DataContract]
属性。
我不想硬编码类的已知类型,比如在Person类中放置[ServiceKnownType(typeof(Employee))]
,以便WCF知道Employee是Person的子类。
现在,我在主机的App.config中添加了以下XML配置:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="Person, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral,PublicKeyToken=null">
<knownType type="Employee, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral, PublicKeyToken=null" />
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
<system.serviceModel>
.......
</system.serviceModel>
</configuration>
我编译了它,运行主机,在客户端添加了服务引用并添加了一些代码并运行客户端。但是发生了错误:
格式化程序抛出异常 试图反序列化消息: 尝试时出错 反序列化参数
http://www.herbertsabanal.net:person
。 InnerException消息是'错误 在第1行的位置247.元素'http://www.herbertsabanal.net:person'
包含的数据'http://www.herbertsabanal.net/Data:Employee'
数据合同。解串器没有 任何映射到的类型的知识 这份合同。添加类型 对应于'员工'到 已知类型列表 - 例如,by 使用KnownTypeAttribute属性 或者将其添加到已知的列表中 传递给的类型 DataContractSerializer的。“。请参阅 InnerException以获取更多详细信息。
以下是数据合同:
[DataContract(Namespace="http://www.herbertsabanal.net/Data", Name="Person")]
class Person
{
string _name;
int _age;
[DataMember(Name="Name", Order=0)]
public string Name
{
get { return _name; }
set { _name = value; }
}
[DataMember(Name="Age", Order=1)]
public int Age
{
get { return _age; }
set { _age = value; }
}
}
[DataContract(Namespace="http://www.herbertsabanal.net/Data", Name="Employee")]
class Employee : Person
{
string _id;
[DataMember]
public string ID
{
get { return _id; }
set { _id = value; }
}
}
顺便说一下,我没有为我的服务使用类库(WCF类库或非WCF类库)。我只是在主机项目中对其进行了简单的编码。
我猜配置文件一定有问题(请参阅上面的配置文件)。或者我必须遗漏一些东西。任何帮助都会非常感激。
答案 0 :(得分:8)
我想我现在找到了答案。
我上面发布的配置文件如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="Person, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral,PublicKeyToken=null">
<knownType type="Employee, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral, PublicKeyToken=null" />
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
<system.serviceModel>
.......
</system.serviceModel>
</configuration>
我刚刚添加的内容是 Person 类的命名空间和 Employee 类。并且不需要更长的版本和文化值....正确的配置应该是:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="WCFWithNoLibrary.Person, WCFWithNoLibrary">
<knownType type="WCFWithNoLibrary.Employee, WCFWithNoLibrary" />
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
<system.serviceModel>
.......
</system.serviceModel>
</configuration>
现在它更短,更有意义。但是如果使用第三方库,则需要添加版本,文化,publickeytokens。
答案 1 :(得分:6)
我知道很久以前就已经回答了这个问题,但是,另一个(对于未来的程序员来说可能更为明显)解决方案:
[KnownType(typeof(SubClass))]
public class BaseClass
斯科特
答案 2 :(得分:0)
在另一种情况下,我也收到了这个冗长的错误消息。我确实使用了KnownTypeAttribute
并成功部署了一个使用WCF.RIA
生成的应用程序。在第二个版本中,我添加了一个新的子类型,并添加了必要的相应KnownTypeAttribute
(编译器在没有此属性的情况下不接受它 - 很棒)。然而,编译器接受的内容以及在我的机器上运行的内容并没有在生产中运行。只有在制作中我才得到上面提到的错误。比较现有子类型和新子类型的所有用法,我忘记了WCF.RIA
要求在方法名称中使用子类型的名称,例如GetMySubTypes。因此,如果在添加属性后出现此错误,请查看是否因为WCF.RIA
惯例。