2012-10-12 63 views
5

En Asamblea A:deserializar tipo derivado usando DataContractSerializer cuando tipo derivado no se conoce de antemano

[DataContract]  
     public class Base 
     { 
      [DataMember] 
      public string SomeText { get; set; } 
     } 

En Asamblea B:

internal class Helper 
     { 
      internal static Base Deserialize(string serializedInstanceOfTypeBase) 
    { 
        DataContractSerializer serializer = new DataContractSerializer(typeof (Base)); 
        XmlReader reader = XmlReader.Create(new StringReader(serializedInstanceOfTypeBase)); 
        return (Base)serializer.ReadObject(reader); 
    } 
    } 

En Asamblea C:

[DataContract]  
     public class Derived : Base 
     { 
      [DataMember] 
      public string SomeMoreText { get; set; } 
     } 

Si serializar una instancia de tipo Derived y pasarlo a Helper.Deserialize() método, se produce un error con el SerializationException:

Error en la línea 1 la posición 2. Contar elemento 'base' de espacio de nombres 'http: // esquemas .datacontract.org/2004/07' .. Se encontró 'Elemento' con el nombre 'Derivados', espacio de nombres 'http://schemas.datacontract.org/2004/07'.

¿Cómo me puedo deshacer de este problema?

Conozco el atributo KnownType, pero a la hora de codificar en el conjunto A y B, no estoy absolutamente enterado de sus tipos derivados. Entonces no puedo usar esa solución.

Diseño de mi producto es más complejo que no puedo publicar aquí en su totalidad. Helper.Desrialize() método sólo se pone un argumento string. No hay manera (en la actualidad al menos) para el montaje A o B, a saber acerca de los tipos derivados de Base clase, incluso en tiempo de ejecución.

Asamblea B de la Asamblea referencias A. Pero un & B no pueden hacer referencia montaje C.

estoy usando C# 4.0. Está bien si la solución que proporciona NO está usando DataContractSerializer.

+1

No tengo conocimiento de una solución lista para usar. Sé que en mi experiencia, cuando tenía una gran variedad de tipos, en realidad duplicaba mi contenido con información de tipo. Es decir, me gustaría tener un 'SerializedObject' que contendría información completa Tipo (nombre de ensamblado, el nombre completo de la clase), junto con su cadena XML serializado.Mi capa de transferencia de datos se escribiría fuertemente contra 'SerializedObject', tomaría una referencia de tiempo de ejecución para el tipo (digamos a través de' Type.GetType'), luego deserializaría los datos XML en consecuencia a través de un XmlSerializer. –

+0

¿Quiere decir que la clase 'Base' está en la 'Asamblea A' y que la clase 'Derivada' está en 'Conjunto C'? Si esto es así, entonces creo que este es el problema. Los Contratos de Datos deben definirse en el mismo conjunto. DataContracts no se debe dividir entre ensamblados. – jags

Respuesta

2

¿Conoce los tipos en tiempo de ejecución ? Si es así, un enfoque simple puede ser justo:

List<Type> knownTypes = ...; // now that you know what to expect 
DataContractSerializer serializer = new DataContractSerializer(
    typeof(Base), knownTypes); 
+0

Gracias por su respuesta. Es muy útil, pero he agregado más detalles a la pregunta. Debería haber agregado esos detalles antes. Tenga en cuenta que la clase 'Helper' está en ensamblaje diferente y no es' public'. Además, el método 'Deserialize' simplemente obtiene cualquier valor de cadena. – Learner

Cuestiones relacionadas