WCF:配置已知类型WCF:配置已知类型(WCF: Configuring Known Types)

2019-05-12 06:39发布

我想知道的是如何在WCF配置已知类型。 例如,我有一个Person类和一个Employee类。 EmployeePerson类的sublass。 两个类标有[DataContract]属性。

我不想硬编码已知类型的一类,就像把一个[ServiceKnownType(typeof(Employee))]在Person类,使WCF就会知道,员工是人的一个子类。

现在,我加入到主机的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'数据的合同。 解串器没有映射到本合同的任何类型的知识。 添加对应于“雇员”到已知类型的列表中的类型 - 例如,通过使用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类库)为我服务。 我只是简单的编码它的主体项目。

我想一定是在配置文件中的问题(请参见上面的配置文件)。 或者,我一定是失去了一些东西。 任何帮助将非常感激。

Answer 1:

我想我已经找到答案了。

我上面贴的配置文件看起来是这样的:

<?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将需要。



Answer 2:

我知道这是回答了一个很久以前,但是,解决方案的另一个(为未来的程序员也许更明显):

[KnownType(typeof(SubClass))]
public class BaseClass

斯科特



Answer 3:

我在另一种情况下拿到这个漫长的错误信息也。 我没有使用KnownTypeAttribute并已经成功地部署它使用一个应用程序WCF.RIA生产。 在第二个版本我添加了一个新的亚型,并增加必要的相应KnownTypeAttribute (没有这个属性的编译器不接受它-伟大的)。 什么编译器都接受,什么跑了我的机器上,并没有在生产运行然而,。 只有在生产我上面提到的错误。 比较现有的亚型的所有用途和新发现我忘记了WCF.RIA要求亚型的名称的方法的名称使用,像GetMySubTypes。 所以,如果你已经添加的属性后,得到这个错误,看是否是因为WCF.RIA小号约定。



文章来源: WCF: Configuring Known Types