在上一章节《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);}