4、已知类型。
在序列化的时候,遇到继承关系时候,序列化要注意了,比如说,一个抽象类或接口,有两个子类型,如果对这个抽象类或接口进行序列化的时候就过报未知类型的错误,怎么解决这个问题呢,DataContractSerializer提供了一个已知类型的参数KownTypes的类型集合,只要把所有子类型添加到已知类型中就可以了,举例如下:
序列化方法:
public static void Serialize<T>(T instance,string fileName,params Type[] knownTypes)
{
DataContractSerializer serializer =new DataContractSerializer(typeof(T),knowTypes,int.MaxValue,false,false,null);
using(XmlWriter writer =new XmlTextWriter(fileName,Encoding.UTF8))
{
serializer.WriteObject(write,instance);
}
Process.Start(fileName);
}
抽象类:
[DataContract]
public abstract class OrderBase
{
[DataMember]
public Guid Id{get;set;}
.......
}
[DataContract]
public class Order:OrderBase
{
[DataMember]
public double totalPrice{get;set;}
}
序列化:Order order =new Order();
order.Id=...
....
Serializer<OrderBase>(order,"order.xml",typeof(Order));
在WCF中我们也可以在基类型中添加KnowTypeAttribute特性,把所有子类型都添加进去,如:
[DataContract]
[KnowType(typeof(Order))]
public class OrderBase
{..........}
或者通过一个函数完成,如:
[DataContract]
[KnownType("GetKnowsTypes")]
public class OrderBase
{
public static IEnumerable<Type> GetKnownTypes()
{
yield return typeof(Order);
yiedld return ......//如果有多个子类型,通过这种方式添加
}
...........
}
WCF中也提供了一种通过配置的方式添加已知类型:
<system.runtime.Serialization>
<dataContractSerializer>
<declaredTypes>
<add type="OrderBase">
<knownType type="Order"/>
...........
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.Serialization>
另外一种方式,不用KnowTypesAttribute特性,也可以通过ServiceKnownTypeAttribute特性来完成,这个特性既可以用在类上,也可以用在接口上,由于,接口里没有办法实现具体的得到已知类型列表的方法,所有多了一个decalringType的构造函数,指定了获取已知类型方法的具体的 类,如:
[ServiceContract]
[ServiceKnownType("GetKnownTypes",Typeof(KnownTypeResolver)]
public interface IContract
{
[OperationContract]
void DoSomething(OrderBase base);
}
public static class KnownTypeResolver
{
public static IEnmerable<Type> GetKnownTypes()
{
yield return typeof(Order);
............
}
}
浙公网安备 33010602011771号