共用方式為


使用資料合約解析程式

數據合約解析程式可讓您動態設定已知類型。 當序列化或反序列化數據契約中未預期的類型時,需要已知的類型。 如需已知型別的詳細資訊,請參閱 數據合約已知型別。 已知型別通常以靜態方式指定。 這表示您在實作操作時,必須了解操作可能接收的所有類型。 在某些情況下,這並非事實,而且能夠動態地指定已知類型是很重要的。

建立數據合約解析程式

建立資料合約解析程式需要實作兩個方法,分別是 TryResolveTypeResolveName。 這兩種方法分別實作於串列化和解串列化過程中使用的回調函數。 方法 TryResolveType 會在串行化期間叫用,並採用數據合約類型,並將其對應至 xsi:type 名稱和命名空間。 方法 ResolveName 會在還原串行化期間叫用,並取得 xsi:type 名稱和命名空間,並將其解析為數據合約類型。 這兩種方法都有參數 knownTypeResolver ,可用來在實作中使用預設的已知型別解析程式。

下列範例示範如何實作 DataContractResolver,以進行對應與映射至一個名為 Customer 的資料合約型別,其衍生自資料合約型別 Person

public class MyCustomerResolver : DataContractResolver  
{  
    public override bool TryResolveType(Type dataContractType, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)  
    {  
        if (dataContractType == typeof(Customer))  
        {  
            XmlDictionary dictionary = new XmlDictionary();  
            typeName = dictionary.Add("SomeCustomer");  
            typeNamespace = dictionary.Add("http://tempuri.com");  
            return true;  
        }  
        else  
        {  
            return knownTypeResolver.TryResolveType(dataContractType, declaredType, null, out typeName, out typeNamespace);  
        }  
    }  
  
    public override Type ResolveName(string typeName, string typeNamespace, DataContractResolver knownTypeResolver)  
    {  
        if (typeName == "SomeCustomer" && typeNamespace == "http://tempuri.com")  
        {  
            return typeof(Customer);  
        }  
        else  
        {  
            return knownTypeResolver.ResolveName(typeName, typeNamespace, null);  
        }  
    }  
}  

一旦您定義了DataContractResolver,您可以透過將它傳遞至DataContractSerializer的建構函式來使用它,如下列範例所示。

XmlObjectSerializer serializer = new DataContractSerializer(typeof(Customer), null, Int32.MaxValue, false, false, null, new MyCustomerResolver());  

您可以在 呼叫 DataContractResolverDataContractSerializer.ReadObject 方法中指定 DataContractSerializer.WriteObject ,如下列範例所示。

MemoryStream ms = new MemoryStream();  
DataContractSerializer serializer = new DataContractSerializer(typeof(Customer));  
XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(XmlWriter.Create(ms));  
serializer.WriteObject(writer, new Customer(), new MyCustomerResolver());  
writer.Flush();  
ms.Position = 0;  
Console.WriteLine(((Customer)serializer.ReadObject(XmlDictionaryReader.CreateDictionaryReader(XmlReader.Create(ms)), false, new MyCustomerResolver()));  

或者,您可以在 上 DataContractSerializerOperationBehavior 設定它,如下列範例所示。

ServiceHost host = new ServiceHost(typeof(MyService));  
  
ContractDescription cd = host.Description.Endpoints[0].Contract;  
OperationDescription myOperationDescription = cd.Operations.Find("Echo");  
  
DataContractSerializerOperationBehavior serializerBehavior = myOperationDescription.Behaviors.Find<DataContractSerializerOperationBehavior>();  
if (serializerBehavior == null)  
{  
    serializerBehavior = new DataContractSerializerOperationBehavior(myOperationDescription);  
    myOperationDescription.Behaviors.Add(serializerBehavior);  
}  
  
SerializerBehavior.DataContractResolver = new MyCustomerResolver();  

您可以實作可套用至服務的屬性,以宣告方式指定數據合約解析程式。 如需詳細資訊,請參閱 KnownAssemblyAttribute 範例。 此範例會實作名為 「KnownAssembly」 的屬性,該屬性會將自定義數據合約解析程式新增至服務的行為。

另請參閱