使用 NetDataContractSerializer 共享类型
在上一章节《WCF可序列化方式》 提到了NetDataContractSerializer 适用于客户端与服务端共享类型信息,支持支持类型不变性。 但并没有提供现成的特性,所以无法使用对数据契约进行标记的方式来达到使用NetDataContractSerializer的目的,必须通过自定制开发,才能对操作契约进行标注。
1. NetDataContractFormatAttribute特性;
public class NetDataContractFormatAttribute : Attribute, IOperationBehavior { public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { ReplaceDataContractSerializerOperationBehavior(operationDescription); } public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation) { ReplaceDataContractSerializerOperationBehavior(operationDescription); } public void Validate(OperationDescription operationDescription) { } public static void ReplaceDataContractSerializerOperationBehavior(OperationDescription description) { DataContractSerializerOperationBehavior dcs = description.Behaviors.Find<DataContractSerializerOperationBehavior>(); if (dcs != null) { description.Behaviors.Remove(dcs); } description.Behaviors.Add(new NetDataContractSerializerOperationBehavior(description)); } }
2. NetDataContractSerializerOperationBehavior 行为;
public class NetDataContractSerializerOperationBehavior : DataContractSerializerOperationBehavior { private static NetDataContractSerializer serializer = new NetDataContractSerializer(); public NetDataContractSerializerOperationBehavior(OperationDescription operationDescription) : base(operationDescription) { } public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes) { return NetDataContractSerializerOperationBehavior.serializer; } public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes) { return NetDataContractSerializerOperationBehavior.serializer; } }
3. 将特性标记在契约中;
[ServiceContract(CallbackContract = typeof(IStockServiceCallback))] public interface IStockService { [OperationContract] double GetPrice(string ticker); [OperationContract(IsOneWay = true)] void RegisterForUpdate(string ticker); [OperationContract] [NetDataContractFormat] StockPrice GetStockPrice(string ticker); }