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