使用WCF服务传递实例化的类
本文关键字:实例化 WCF 服务 使用 | 更新日期: 2023-09-27 18:24:06
我有一个C#类库,它包含大约50个类和数百个属性。实例化我的类可能需要一段时间,因此作为优化,我正在考虑在服务器上实例化它们,然后让服务器通过WCF服务将实例化的类传递给客户端应用程序。
看起来应该很好用。然而,据我所知,如果我想这样做,我不仅需要将每个类标记为[DataContract]
,还需要将每个属性标记为[DataMember]
。这真的是真的吗?需要这样做似乎很疯狂,尤其是在每一处房产上。有没有一种方法可以说整个类都是可序列化的,而不必经过这个过程?
如果使用[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知道如何序列化这些类。如果没有这些属性,这些属性就不会被序列化,您也不会在客户端中看到该字段或类。
在一个真正的独立客户端-服务器场景中,你必须这样做。(如果你不能共享一个文件。)