使用WCF服务传递实例化类

时间:2012-02-09 13:59:24

标签: c# wcf serialization service

我有一个C#类库,大约有50个类,有数百个属性。实例化我的类可能需要一段时间,因此作为优化,我考虑将它们在服务器上实例化,然后让服务器通过WCF服务将实例化的类传递给客户端应用程序。

似乎应该可以正常工作。但是,根据我的理解,如果我想这样做,我不仅要将每个类标记为[DataContract],还要将每个属性标记为[DataMember]。这是真的吗?看起来很疯狂,这需要做,特别是在每个房产上。有没有办法说整个类是可序列化的,而不必经历这个过程?

4 个答案:

答案 0 :(得分:3)

如果您使用[DataContract],则还需要为每个成员指定[DataMember]

或者 - 使用[Serializable]标记该类,并且序列化程序将为您序列化所有内部结构,除非您另有明确说明([Serializable]适用于选择退出方法,而[DataContract]适用于选择加入方式)。

然而 - 取决于您正在尝试做什么 - 这种方法可能存在缺陷。

当您通过WCF传递对象时,您根本没有真正传递该对象 - 您正在传递该对象的副本。实际上,原始对象将被序列化,传递到线路并在另一端反序列化。这意味着客户端仍然必须实例化重构该类的实例,然后填充所有属性。你可能什么也得不到,而且可能会有一个相当昂贵的电话,大量数据通过网络传递。

所以这一切都取决于你在做什么。如果您不介意客户端获取实例的副本,并且费用不是由于大量数据而是由于数据库访问速度慢等其他因素,那么很好。否则你的方法可能不会给你买任何东西。

顺便说一下,在.Net远程处理中,可以引用一个远程对象(即客户端可以引用服务器上的对象) - 如果类型本身来自MarshalByRefObject,那就是不是WCF的情况 - 你最终在本地使用自己的副本。

答案 1 :(得分:2)

  

如果我想这样做,我不仅需要将每个班级标记为   [DataContract]也是[DataMember]的每个属性。这是真的吗   真?

是和否。

如果客户端代码无法导入包含这些类的程序集,那么是的,您需要将它们标记出来。这样WCF就可以告诉客户端如何解释结果集。

如果您可以在WCF服务客户端(例如POCO库)中使用通用程序集,则无需应用这些属性。 WCF将告诉客户通过它的强名来引用程序集。

以下是#2中的WSDL的样子:

<wsdl:types>
  <xsd:schema targetNamespace = "http://tempuri.org/Imports">
    <xsd:import schemaLocation = "http://localhost:12902/MyService.svc?xsd=xsd0"
       namespace="http://tempuri.org/" />
    <xsd:import schemaLocation = "http://localhost:12902/MyService.svc?xsd=xsd1"
       namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
    <xsd:import schemaLocation = "http://localhost:12902/MyService.svc?xsd=xsd2"
      namespace="http://schemas.datacontract.org/2004/07/MyAssembly.MyProject" />
  </xsd:schema>
</wsdl:types>

上面的MyAssembly.MyProject指的是程序集中的命名空间。如果您按照http://localhost:12902/MyService.svc?xsd=xsd2处的链接(当然在本地计算机上),您将获得一个XSD,描述在该命名空间内序列化的实体。你不必装饰这个类。 WCF会为您完成所有这些工作。

答案 2 :(得分:0)

基本上是的。它需要在类,结构,字段上具有两个属性,以便NET知道序列化这些类。如果没有这些属性,那些将不会被序列化,您将不会在客户端中看到该字段或类。

答案 3 :(得分:0)

在真实的单独客户端服务器方案中,您必须这样做。 (如果你不能共享文件。)