2010-08-26 18 views
7

Tengo una clase base con propiedades DataMember. También tengo una clase derivada con propiedades de DataMember. En mi proyecto WCF estoy devolviendo la clase derivada. ¿Hay alguna manera de evitar que un miembro de mi clase base se serialice? Aquí hay un código de ejemplo:WCF DataContract Excluir DataMembers de Ser serializados en clases derivadas

public class BaseClass 
{ 
    public string ShortDescription {get;set;} 
    public string LongDescription {get;set;} 
} 

public class DerivedClass : BaseClass 
{ 
    public List<Description> Descriptions {get;set;} 
} 

En este código Quiero ser capaz de ocultar los miembros heredados shortDescription y longdescription porque ahora son obsoletos. Cualquier intento de hacerlo ha sido infructuoso. Esto es lo que he intentado:

public class DerivedClass : BaseClass 
{ 
    [DataMember] 
    public List<Description> Descriptions {get;set;} 

    // override the base class members 
    [IgnoreDataMember]  
    public override string ShortDescription {get;set;} 
    [IgnoreDataMember] 
    public override string LongDescription {get;set;} 
} 

y

public class DerivedClass : BaseClass 
{ 
    [DataMember] 
    public List<Description> Descriptions {get;set;} 

    // shadow the base class members 
    [IgnoreDataMember]  
    public new string ShortDescription {get;set;} 
    [IgnoreDataMember] 
    public new string LongDescription {get;set;} 
} 

Ninguno de estos enfoques han funcionado. El tipo "DerivedClass" cuando se envía a WSDL todavía contiene los miembros "Ignorados" del tipo de clase base.

Puede preguntarse por qué no estoy cambiando la clase base. Esto se debe a que todavía utilizo la clase base en su forma original como la versión anterior del tipo para que el WSDL admita la compatibilidad con versiones anteriores para los consumidores. De esta manera puedo tener una llamada v1000 que devuelve BaseClass y una llamada V1010 que devuelve una DerivedClass. Puedo agregar y cambiar la funcionalidad de DerivedClass todo lo que quiero sin el potencial de afectar a los consumidores de la funcionalidad de v1000.

Respuesta

2

Eventualmente encontré una forma adecuada de manejar esta tarea. No tengo el código delante de mí, así que voy a escribir la sintaxis. Es una solución bastante simple, pero resuelve el problema específico que estaba teniendo.

public class BaseClass 
{ 
    // leave this guy empty 
} 

public class DerivedClassVersion1 : BaseClass 
{ 
    [DataMember] 
    public string ShortDescription {get;set;} 

    [DataMember] 
    public string LongDescription {get;set;} 
} 

public class DerivedClassVersion2 : BaseClass 
{ 
    [DataMember] 
    public List<Description> Descriptions {get;set;} 
} 

Badda bing! Bastante simple, pero es lo que necesitaba.

0

Prueba esto:

public class BaseClass 
{ 
    [DataMember] 
    public virtual string ShortDescription {get;set;} 

    [DataMember] 
    public virtual string LongDescription {get;set;} 
} 

public class DerivedClass : BaseClass 
{ 
    [DataMember] 
    public List<Description> Descriptions {get;set;} 

    public override string ShortDescription {get;set;} 
    public override string LongDescription {get;set;} 
} 

EDIT: Tal vez la utilización de contratos de mensajes para controlar con precisión la serialización podrían trabajar: http://msdn.microsoft.com/en-us/library/ms730255.aspx

lo contrario, también puede buscar en la implementación de un 'router WCF' que le permitiría utilizar el mismo punto final, pero enrutar diferentes versiones a diferentes servicios.

+1

Esto produce el mismo resultado. Curiosamente, si realizo la anulación y proporciono el atributo [DataMember] en un intento de mostrarlo en la definición XML de DerivedClass, aún no aparece en DerivedClass, sino en la clase base. – omatase

+0

Hrmmpf ... sí, eso no funciona;) – Kwal

6

Intente agregar el atributo [DataContract] a ambas clases. Esto le indicará al serializador que mire los atributos [DataMember] y [IgnoreDataMember]. Sin que la clase sea atribuida con [DataContract], todos los miembros públicos son serializados.

[DataContract] 
public class BaseClass 
{ 
    [IgnoreDataMember] 
    public string ShortDescription {get;set;} 

    [IgnoreDataMember] 
    public string LongDescription {get;set;} 
} 

[DataContract] 
public class DerivedClass : BaseClass 
{ 
    [DataMember] 
    public List<Description> Descriptions {get;set;} 
} 

Además, sería aún mejor para agregar un espacio de nombres a sus DataContracts especificándolo en el [DataContract (Espacio de nombres = "...")] atributo. Eso rompería a los clientes antiguos que llaman a su servicio actualizado.

+0

Merece la pena señalar que WITH [DataContract] en la clase ya no necesita la explotación [IgnorDataMember], ya que solo los miembros con [DataMember] se incluirán en el transporte. – Ricibob

Cuestiones relacionadas