2011-09-12 23 views
12

Estoy usando un DataContractJsonSerializer y tengo un problema con el DataMember Name.Serialization DataMember (name) override issue

Hice una clase base y varias clases derivadas. Necesito las clases derivadas porque tengo diferentes cadenas json. Quiero deserializar las cadenas json y, por lo tanto, necesito nombres diferentes para los miembros de la data. Trato de cambiar el nombre DataMember como en el siguiente ejemplo:

BaseClass:

[DataContract] 
public abstract class BaseClass 
{ 


    [DataMember] 
    public virtual string FirstMethod { get; protected set; } 

} 

clase derivada:

[DataContract] 
[KnownType(typeof(BaseAccess))] 
public class DerivedClass 
{ 


    [DataMember(Name="first_method")] 
    public virtual string FirstMethod { get; protected set; } 

} 

El problema es que cuando se utiliza una clase derivada la serialización parece ignorar el nombre de DataMember dado. Entonces, cuando me deserializo con el tipo DerivedClass, la serialización parece tener lugar con el nombre "FirstMethod" (de la clase base) en lugar de "first_method" (de la clase derivada). ¿Es posible usar el nombre de DataMember de la clase derivada (que es diferente para varias clases derivadas en mi situación).

Otra pregunta. Encontré ejemplos con KnownType agregado en la clase base y agregado en la clase derivada. Me parece lógico hacerlo en la clase derivada (especialmente por cuestiones de herencia). ¿Que es correcto?

Respuesta

7

Tuve este mismo problema. Estaba usando VB.NET y tuve que sombrear (o sobrecargar) la propiedad para que WCF respetara la propiedad DataMember en mi clase derivada. En C#, debería poder usar el nuevo operador.

public class DerivedClass 
{ 
    [DataMember(Name = "first_method")] 
    new public string FirstMethod { get; protected set; } 
} 
+0

Tenga en cuenta que para evitar la creación de dos campos en su JSON, deberá eliminar el atributo [DataMember] de la propiedad en la clase base. –

3

El truco es especificar EmitDefaultValue = false para el miembro de datos virtual de la clase base, y en su aplicación en el valor por defecto de retorno clase derivada por lo que el miembro de datos no es de serie. En la clase derivada, defina otro miembro de datos con el nombre requerido.

[DataContract(Name = "baseclass", Namespace = "")] 
[KnownType(typeof(DerivedClass))] 
public class BaseClass 
{ 
    [DataMember(Name = "attributes", EmitDefaultValue = false)] 
    public virtual SomeType Fields { get; set; } 
} 

[DataContract(Name = "derivedclass", Namespace = "")] 
public class DerivedClass : BaseClass 
{ 
    public override SomeType Fields 
    { 
     get { return null; } 
    } 

    [DataMember(Name = "fields")] 
    public SomeType DerivedFields 
    { 
     get { return base.Fields; } 
    } 
}