2011-02-28 4 views
5

que tienen dos clases y un método web de la siguiente manera¿Por qué mis campos de clase base no se serializan al devolver objeto de clase derivado de un método web ASMX?

[Serializable] 
public class BaseClass 
{ 
    public int Key; 
    public bool IsModified; 
    public bool IsNew; 
    public bool IsDeleted; 
} 

[Serializable] 
public class DerivedClass : BaseClass 
{ 
    public string Name; 
} 

[WebMethod] 
public List<DerivedClass> GetDerivedClassObjects() 
{ 

} 

Pero cuando veo la respuesta SOAP, no veo los campos de la clase base. ¿No se supone que deben ser serializados? Si quisiera que se serialicen, ¿qué se debe hacer?

+1

¿pregunta duplicada? vea http://stackoverflow.com/questions/1262246/asmx-web-service-not-serializing-abstract-base-class – KBoek

+0

¿Qué está devolviendo en 'GetDerivedClassObjects()' Debería funcionar bien, sin hacer nada especial . –

+0

y todo: '[Serializable]' es ignorado por XmlSerializer. –

Respuesta

3

Puede eliminar los [Serializable] atributos de sus clases, esto debería funcionar sin él. Las POCO no requieren que el atributo esté presente, se serializan bien tal como están.

Editar: ¿Ha comprobado realmente cuál es la salida del servicio web o solo está mirando la definición del mensaje en el punto final web del servicio?

puedo ver que el formato de mensaje SOAP generada cuando explora el punto final del servicio en su navegador parece no saber nada acerca de los campos de la clase base:

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soap:Body> 
    <GetDerivedClassObjectsResponse xmlns="http://tempuri.org/"> 
     <GetDerivedClassObjectsResult> 
     <DerivedClass> 
      <Name>string</Name> 
     </DerivedClass> 
     <DerivedClass> 
      <Name>string</Name> 
     </DerivedClass> 
     </GetDerivedClassObjectsResult> 
    </GetDerivedClassObjectsResponse> 
    </soap:Body> 
</soap:Envelope> 

Pero cuando se llama al servicio web utilizando el formulario de prueba, o Storm, la clase se serializado:

<DerivedClass> 
    <Key>1</Key> 
    <IsModified>true</IsModified> 
    <IsNew>true</IsNew> 
    <IsDeleted>true</IsDeleted> 
    <Name>Test1</Name> 
</DerivedClass> 

el estudio visual "Agregar referencia web" diálogo también crea las clases de proxy correctamente.

Editar 2: En cuanto a la definición de servicios web (? Service.asmx WSDL) generada por nosotros, podemos ver que la definición conserva la jerarquía de herencia original, en lugar de aplanar el objeto hasta sus campos en el proceso de serialización:

<s:complexType name="DerivedClass"> 
    <s:complexContent mixed="false"> 
     <s:extension base="tns:BaseClass"> 
      <s:sequence> 
       <s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" /> 
      </s:sequence> 
     </s:extension> 
    </s:complexContent> 
</s:complexType> 
<s:complexType name="BaseClass"> 
    <s:sequence> 
     <s:element minOccurs="1" maxOccurs="1" name="Key" type="s:int" /> 
     <s:element minOccurs="1" maxOccurs="1" name="IsModified" type="s:boolean" /> 
     <s:element minOccurs="1" maxOccurs="1" name="IsNew" type="s:boolean" /> 
     <s:element minOccurs="1" maxOccurs="1" name="IsDeleted" type="s:boolean" /> 
    </s:sequence> 
</s:complexType> 

Curiosamente, parece que el mensaje de la muestra generada en el extremo de servicio no toma en cuenta la extensión. Pero para todos los demás efectos y propósitos, su código debería funcionar en.

+0

Sí, tienes razón. Cuando creé la clase de proxy, pude ver todos los campos de mi clase base. También tenía el atributo [XmlInclude (typeof (BaseClass)] para el método web. – logik6

1

Tiene que agregar el atributo KnownType a la clase base.

[Serializable] 
[KnownType(typeof(DerivedClass)] 
public class BaseClass 
{ 
    ... 
} 
+0

-1: Está usando un servicio ASMX. 'KnownType' es para WCF. –

+0

Me temo que no funcionó para mí. Pero aprendí algo hoy. Hice los cambios pero todavía no muestra los campos en SOAP. FYI, estoy usando .Net 3.5 – logik6

Cuestiones relacionadas