返回基础对象列表的服务方法给我“复杂类型不能指定KnownTypeAttribute”消息

时间:2011-12-23 16:22:44

标签: .net silverlight wcf-ria-services

我正在使用WCF RIA Services将自定义数据传输对象返回给Silverlight客户端。

我想返回一个对象,比如FruitBasket(类似于this post),它包含一个Fruits列表。 Fruit类是派生类的基类,例如Apple,Pear,Peach等。在运行时,Fruits列表可以包含任何派生类型。我希望RIA Services对整个FruitBasket对象进行序列化和反序列化,包括其Fruit的集合。

  • 如果我只是定义我的类层次结构并返回整个FruitBasket对象,则会出现运行时错误:
  

预计不会输入数据合约名称为“Peach:http://schemas.datacontract.org/2004/07/FruitApp”的“Peach”。考虑使用DataContractResolver或将任何静态未知的类型添加到已知类型列表中 - 例如,使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。

  • 如果我在Fruit类上指定[KnownType(typeof(Peach))]属性,则会出现编译时错误:
  

复杂类型'Fruit'无效。复杂类型无法指定   KnownTypeAttribute。

如何设置我的数据模型以便我可以访问客户端上的Fruit集合?在客户端,如果对象仅被识别为“Fruit”对象,则甚至可以。我只需要它们反序列化。

2 个答案:

答案 0 :(得分:2)

RIA Services支持2种用户类型:复杂类型和实体类型。实体是一个持久对象,具有唯一标识它的键。复杂类型只是将几个基本类型字段分组为单个对象。它们不适用于类和层次结构的通用概念,它们限制了您可以或不可以做的事情,以便更有效地解决某些特定问题。

其中一个限制是复杂类型不能具有派生类型。很难说为什么,但我认为没有限制,框架就会复杂得多。

现在,有几种方法可以解决这个问题:

  1. 如果您的Fruit课程中已有适当的密钥(例如,数据库ID),请使用[Key]属性进行标记。
  2. 如果您没有密钥但又不在乎,请添加一个返回Guid的{​​{1}}属性,并将其标记为Guid.NewGuid(),您就可以了。 注意,在这种情况下,您将无法与[Key]个实体建立任何关系,也无法将更改保存回服务器。
  3. 不要使用继承。如果不是真的有必要,为什么不在没有它的情况下生活呢?
  4. 使用普通的WCF。 RIA服务不是通用案例通信框架。它们对所有这些实体 - 关系的东西都非常具体。
  5. 由您决定是否取决于您的要求。

答案 1 :(得分:0)

显然,WCF RIA Services会将没有KeyAttribute的任何类视为复杂类型,从而抛出错误。

因此,如果您的Fruit基类中有一个可用作键的属性,则使用[Key]进行装饰应解决复杂类型错误消息。