【问题标题】:WCF: Configuring Known TypesWCF:配置已知类型
【发布时间】:2009-02-18 08:10:18
【问题描述】:

我想知道如何在 WCF 中配置已知类型。例如,我有一个 Person 类和一个 Employee 类。 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' 数据合同。解串器没有 映射到的任何类型的知识 这份合同。添加类型 对应于 '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 类库)。我只是在宿主项目中对其进行了简单的编码。

我想配置文件肯定有问题(请参阅上面的配置文件)。或者我一定错过了什么。任何帮助将不胜感激。

【问题讨论】:

  • 我怀疑配置只有在使用第三方库时才有效,将其引用到服务。我会尝试一下,如果我找到一些答案,我会回到这个问题。

标签: wcf wcf-configuration


【解决方案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 类的命名空间。并且不需要更长的 Version 和 Culture 值......正确的配置应该是:

<?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>

现在它更短,更有意义。但如果使用 3rd 方库,则需要添加版本、文化、publickeytokens。

【讨论】:

  • 点赞。您是否必须在客户端 .config 上做任何事情?
  • 您需要在客户端复制配置,以便接收新类型。
【解决方案2】:

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

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

斯科特

【讨论】:

  • 如果子类型在不同的项目中,这并不总是可行的
【解决方案3】:

在另一种情况下,我也收到了这个冗长的错误消息。我确实使用了KnownTypeAttribute,并成功地将一个使用WCF.RIA 的应用程序部署到了生产环境中。在第二个版本中,我添加了一个新的子类型,并添加了必要的对应KnownTypeAttribute(如果没有这个属性,编译器不会接受它——太好了)。然而,编译器接受的内容以及在我的机器上运行的内容并没有在生产中运行。只有在生产中我才得到上面提到的错误。比较现有子类型和新子类型的所有用途后发现,我忘记了WCF.RIA 要求在方法名称中使用子类型的名称,例如 GetMySubTypes。所以如果你在添加属性后出现这个错误,看看是不是因为WCF.RIAs 的约定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 1970-01-01
    相关资源
    最近更新 更多