使用WCF服务传递实例化的类

本文关键字:实例化 WCF 服务 使用 | 更新日期: 2023-09-27 18:24:06

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

看起来应该很好用。然而,据我所知,如果我想这样做,我不仅需要将每个类标记为[DataContract],还需要将每个属性标记为[DataMember]。这真的是真的吗?需要这样做似乎很疯狂,尤其是在每一处房产上。有没有一种方法可以说整个类都是可序列化的,而不必经过这个过程?

使用WCF服务传递实例化的类

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

或者,用[Serializable]标记类,除非您明确表示不这样做,否则序列化程序将为您序列化所有内部([Serializable]适用于选择退出方法,而[DataContract]适用于选择加入方法)。

然而,这种方法可能存在缺陷,具体取决于你想做什么。

当您通过WCF传递对象时,您根本不是在传递对象——您传递的是对象的副本。事实上,原始对象将被序列化、传递到另一端并反序列化。这意味着客户端仍然需要实例化重构类的实例,然后填充所有属性。你可能一无所获,而且可能会有一个相当昂贵的调用,大量数据通过导线传输。

所以这完全取决于你在做什么。如果你不介意客户端获得实例的副本,如果费用不是由于数据量太大,而是由于数据库访问速度慢等其他原因,那就好了。否则,你的方法可能不会给你带来任何好处。

顺便说一句,在.Net远程处理中,可以引用远程对象(即客户端可以引用服务器上的对象)-如果类型本身派生自MarshalByRefObject,但WCF并非如此-那么您最终会在本地获得自己的副本。

如果我想这样做,我不仅需要将每个类标记为[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为您完成所有这些。

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

在一个真正的独立客户端-服务器场景中,你必须这样做。(如果你不能共享一个文件。)