다음을 통해 공유


데이터 계약 확인자 사용

데이터 계약 확인자를 사용하면 알려진 형식을 동적으로 구성할 수 있습니다. 알려진 형식은 데이터 계약에 필요하지 않은 형식을 직렬화하거나 역직렬화할 때 필요합니다. 알려진 형식에 대한 자세한 내용은 데이터 계약의 알려진 형식을 참조하세요. 알려진 형식은 일반적으로 정적으로 지정됩니다. 즉, 작업을 구현하는 동안 작업이 받을 수 있는 가능한 형식을 모두 알고 있어야 합니다. 이에 해당하지 않고 알려진 형식을 동적으로 지정하는 기능이 중요한 시나리오도 있습니다.

데이터 계약 확인자 만들기

데이터 계약 확인자를 만드는 작업에는 TryResolveTypeResolveName 메서드를 구현하는 작업이 포함됩니다. 이러한 두 메서드는 serialization 및 deserialization 중에 사용되는 콜백을 각각 구현합니다. TryResolveType 메서드는 serialization 중에 호출되며 데이터 계약 형식을 받아서 xsi:type 이름 및 네임스페이스에 매핑합니다. ResolveName 메서드는 deserialization 중에 호출되며 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());  

다음 예제와 같이 DataContractResolver 또는 DataContractSerializer.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”라는 특성을 구현합니다.

참고 항목