Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Um resolvedor de contrato de dados permite que você configure tipos conhecidos dinamicamente. Tipos conhecidos são necessários ao serializar ou desserializar um tipo não esperado por um contrato de dados. Para obter mais informações sobre tipos conhecidos, consulte Tipos Conhecidos do Contrato de Dados. Os tipos conhecidos normalmente são especificados estaticamente. Isso significa que você teria que saber todos os tipos possíveis que uma operação pode receber durante a implementação da operação. Há cenários em que isso não é verdade e ser capaz de especificar tipos conhecidos dinamicamente é importante.
Criando um resolvedor de contrato de dados
A criação de um resolvedor de contrato de dados envolve a implementação de dois métodos TryResolveType e ResolveName. Esses dois métodos implementam retornos de chamada usados durante a serialização e desserialização, respectivamente. O método TryResolveType é invocado durante a serialização e pega um tipo de contrato de dados e mapeia-o para um nome e namespace xsi:type. O método ResolveName é invocado durante a desserialização e usa um nome e um namespace xsi:type e o resolve para um tipo de contrato de dados. Ambos os métodos têm um knownTypeResolver parâmetro que pode ser usado para usar o resolvedor de tipo conhecido padrão em sua implementação.
O exemplo a seguir mostra como implementar um DataContractResolver para mapear para e de um tipo de contrato de dados chamado Customer derivado de um tipo e contrato de dados 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);
}
}
}
Depois de definir um DataContractResolver, você pode usá-lo passando-o para o construtor DataContractSerializer, conforme mostrado no exemplo a seguir.
XmlObjectSerializer serializer = new DataContractSerializer(typeof(Customer), null, Int32.MaxValue, false, false, null, new MyCustomerResolver());
Você pode especificar um DataContractResolver em uma chamada para os métodos DataContractSerializer.ReadObject ou DataContractSerializer.WriteObject, conforme mostrado no exemplo a seguir.
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()));
Ou você pode defini-lo no DataContractSerializerOperationBehavior conforme mostrado no exemplo a seguir.
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();
Você pode especificar declarativamente um resolvedor de contrato de dados implementando um atributo que pode ser aplicado a um serviço. Para obter mais informações, consulte o exemplo KnownAssemblyAttribute . Este exemplo implementa um atributo chamado "KnownAssembly" que adiciona um resolvedor de contrato de dados personalizado ao comportamento do serviço.