4

我有一个复杂的数据类型,包括许多函数,以及通常的 get 和 get 方法。如果我可以使用 WCF,我的生活会轻松很多,因此我的客户也可以使用这种数据类型。

难道我

  1. 忽略所有操作,[DataMemeber]只放在需要的地方。

  2. 将有问题的类放在一个共享库程序集中,供客户端和服务器访问。

谢谢,罗伯托

PS。我意识到这个问题的措辞可能不够好。

4

5 回答 5

3

跨 WCF 边界传输的所有内容都是被序列化的——这相当于类的状态。方法不会。因此,如果您需要它们在双方都可用,那么您将需要一个您建议的共享库。

添加服务引用时,您可以选择重用数据类型,在这种情况下,WCF 将反序列化为共享类,并带有方法。但实际上只是跨界传输的字段值。

于 2009-07-27T11:28:06.473 回答
3

好的,事实证明是上述所有答案的组合。

  1. 将数据类粘贴到从客户端和服务器项目引用的共享程序集中。
  2. 确保在“配置服务引用”对话框中选中了“在引用的程序集中重用类型”项。
  3. 在每个数据合同的开头放置一个 [KnownType] 属性。

代码如下所示:

[DataContract]
[KnownType(typeof(WHS2SmugmugShared.Photo))]
[KnownType(typeof(WHS2SmugmugShared.PhotoInfo))]
public class Photo
{
//code here
}

在上述情况下,我在 Photo 类中使用 PhotoInfo。PhotoInfo 在类文件中没有与之关联的 KnownType 属性。而且它似乎不是必需的。

这允许您序列化复杂类型,但仍保留它们的操作。

于 2009-07-27T16:56:19.623 回答
1

数据契约的最佳实践是让它成为一个契约——只有数据而没有行为。第二个最佳实践是让您使用 [DataMember] 装饰您的课程,并将其保留在服务器上 - 让客户端使用代理副本。

于 2009-07-27T11:29:48.873 回答
0

简短的回答:是的。WCF 像冠军一样处理复杂类型。传递复杂类型时,您只想关注正在传递的数据。如果您的客户端不共享 DLL,那么只关注正在传递的数据(而不是任何其他操作)就变得更加重要,因为客户端只会获得复杂类型数据成员的副本。

我猜你来自Java背景?使用 WCF,您将需要使用 DataMember 属性标记字段,或者(更好)将您的 get/set 方法更改为属性。

例如,而不是:

[DataContract]
public class Foo
{
   [DataMember]
   private string bar;

   public string GetBar()
   {
      return bar;
   }

   public void SetBar(string b)
   {
      bar = b;
   }
}

您可以使用以下内容:

[DataContract]
public class Foo
{
   [DataMember]
   public string Bar { get; set; }
}
于 2009-07-27T11:28:22.777 回答
0

使用可序列化属性装饰所有此类类型。因此,您不需要为参与 WCF 服务的每个复杂类放置 [DataContract] 属性。

在 WCF 客户端添加包含这些类型的 dll,并让代理重用这些类,而不是重新生成反序列化所需的类。如果将任何类型添加到代理中,请将其删除并从 dll 中使用。通过这种方式,我可以轻松地跨服务共享我的复杂类型。 但仅当您可以将您的类型作为单独的 dll 进行分配时,它才适用。

于 2009-08-06T12:47:30.647 回答