WCF中数据契约已知类型的使用

在Windows Communication Foundation (WCF)中,数据契约是定义服务数据交换格式的一种方式。通常情况下,发送方和接收方都知道数据契约的类型。但在某些情况下,发送回客户端的数据并不是实际的数据契约类型,而是一个派生类型。这时,反序列化引擎将无法识别派生的数据契约类型,并会报错。为了处理这种情况,WCF提供了数据契约已知类型(Known Types)的概念。

数据契约已知类型是指在WCF中,可以接受的派生类型。在之前的WCF服务文章中,通过一个简单的例子解释了WCF的KnownTypeAttribute。但在这个WCF教程中,将尝试讨论使用数据契约已知类型所有可能的方式,以便读者能够详细了解已知类型,并能够在各种实际场景中使用它。

假设有一个服务契约“IVehicleService”,如下所示:

[ServiceContract] public Interface IVehicleService { [OperationContract] Vehicle AddNewVehicle(Vehicle myVehicle); [OperationContract] bool UpdateVehicle(Vehicle myVehicle); }

可以根据需求在不同的级别使用数据契约已知类型:

全局级别

使用基类型代码

使用Web.config

服务契约级别

操作契约级别

要全局使用,可以在基数据契约类型上应用KnownTypeAttribute,如下例所示:

[KnownType(typeof(Car))] [KnownType(typeof(Truck))] [DataContract] public class Vehicle { } [DataContract] public class Car : Vehicle { } [DataContract] public class Truck : Vehicle { }

在上面的例子中,可以看到KnownTypeAttribute是在基数据契约类型Vehicle上使用的。因此,这些派生类型现在对所有服务和操作契约都是全局已知的,无论Vehicle类型在哪里使用。

使用Web.config也可以实现相同的效果,如下所示:

<system.runtime.serialization> <dataContractSerializer> <declaredTypes> <add type="MyService.Vehicle, MyService, Version=, Culture=Neutral, PublicKeyToken=null"> <knownType type="MyService.Car, MyService, Version=, Culture=Neutral, PublicKeyToken=null"/> <knownType type="MyService.Truck, MyService, Version=, Culture=Neutral, PublicKeyToken=null"/> </add> </declaredTypes> </dataContractSerializer> </system.runtime.serialization>

上述配置也会使派生类型(Car、Truck)成为全局已知类型。

在服务契约中使用

在某些场景中,如果想要为特定服务使这些派生类型成为已知类型,可以应用ServiceKnownTypeAttribute,如下所示:

[ServiceKnownType(typeof(Car))] [ServiceKnownType(typeof(Truck))] [ServiceContract] public Interface IVehicleService { [OperationContract] Vehicle AddNewVehicle(Vehicle myVehicle); [OperationContract] bool UpdateVehicle(Vehicle myVehicle); }

现在,这些派生类型是IVehicleService中所有操作契约的已知类型。

为了进一步限制,即只为服务中的特定操作契约,可以这样做:

[ServiceContract] public Interface IVehicleService { [OperationContract] [ServiceKnownType(typeof(Car))] [ServiceKnownType(typeof(Truck))] Vehicle AddNewVehicle(Vehicle myVehicle); [OperationContract] bool UpdateVehicle(Vehicle myVehicle); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485