Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are my base class fields not being serialized when returning derived class object from an ASMX web method?

I have two classes and a web method as follows

[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()
{

}

But when I see the SOAP response, I do not see the fields from the base class. Are they no supposed to be serialized? If I wanted them to be serialized what should be done?

like image 936
logik6 Avatar asked Oct 12 '22 15:10

logik6


1 Answers

You can remove the [Serializable] attributes from your classes, this should work without. POCOs don't require the attribute to be present, they serialize fine as they are.

Edit: Have you actually checked what the web service output is, or are you just looking at the message definition on the service web endpoint?

I can see that the SOAP message format generated when you browse to the service endpoint in your browser doesn't seem to know anything about the base class fields:

<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>

But when you call the web service using the test form, or Storm, the class gets serialized:

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

The visual studio "Add web reference" dialog also creates the proxy classes correctly.

Edit 2: Looking at the web service definition (service.asmx?wsdl) generated for us, we can see that the definition preserves the original inheritance hierarchy, as opposed to flattening the object down to its fields in the serialization process:

<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>

Interestingly enough it seems that the generated sample message at the service endpoint doesn't take the extension into account. But for all other effects and purposes your code should work.

like image 172
jevakallio Avatar answered Oct 14 '22 21:10

jevakallio