Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Un solucionador de contratos de datos permite configurar tipos conocidos dinámicamente. Los tipos conocidos son necesarios al serializar o deserializar un tipo no esperado por un contrato de datos. Para obtener más información sobre los tipos conocidos, vea Tipos conocidos del contrato de datos. Normalmente, los tipos conocidos se especifican estáticamente. Esto significa que tendría que conocer todos los tipos posibles que puede recibir una operación mientras la implementa. Hay escenarios en los que esto no es cierto y es importante poder especificar dinámicamente tipos conocidos.
Creación de un solucionador de contratos de datos
Crear un solucionador de contratos de datos implica implementar dos métodos, TryResolveType y ResolveName. Estos dos métodos implementan devoluciones de llamada que se utilizan durante la serialización y la deserialización respectivamente. El método TryResolveType se invoca durante la serialización y toma un tipo de contrato de datos para asignarlo a un espacio de nombres y a un nombre xsi:type. El método ResolveName se invoca durante la deserialización y toma un espacio de nombres y un nombre xsi:type y lo resuelve como un tipo de contrato de datos. Ambos métodos tienen un knownTypeResolver parámetro que se puede usar para usar el solucionador de tipos conocido predeterminado en la implementación.
En el siguiente ejemplo, se muestra cómo implementar una clase DataContractResolver para realizar asignaciones desde y hacia un tipo de contrato de datos denominado Customer derivado de una Person del tipo de contrato de datos.
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);
}
}
}
Una vez que haya definido un DataContractResolver elemento , puede usarlo pasando al DataContractSerializer constructor como se muestra en el ejemplo siguiente.
XmlObjectSerializer serializer = new DataContractSerializer(typeof(Customer), null, Int32.MaxValue, false, false, null, new MyCustomerResolver());
Puede especificar un DataContractResolver en una llamada a los métodos DataContractSerializer.ReadObject o DataContractSerializer.WriteObject, como se muestra en el siguiente ejemplo.
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()));
O bien, puede establecerlo en el DataContractSerializerOperationBehavior como se muestra en el ejemplo siguiente.
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();
Puede especificar mediante declaración un solucionador de contratos de datos mediante la implementación de un atributo que se puede aplicar a un servicio. Para obtener más información, vea el ejemplo KnownAssemblyAttribute . En este ejemplo se implementa un atributo denominado "KnownAssembly" que agrega un solucionador de contratos de datos personalizado al comportamiento del servicio.