I have in my DataContract a collection of objects defined as
Collection<BaseAbstractObject>
which I want to fill up with some inherited objects of type ClassA.
I'm using Soap UI to create such a request to my service method, but I'll get error "Cannot create an abstract class"
I have also decorated base class with [KnownType(ClassA)] attribute. My xml request looks like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:wcf="http://schemas.datacontract.org/2004/07/WcfService1" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header/>
<soapenv:Body>
<tem:GetDataUsingDataContract>
<tem:composite>
<wcf:ClassesCollection>
<wcf:BaseClass i:type="ClassA" >
<wcf:Id>1</wcf:Id>
<wcf:Name>ClassA</wcf:Name>
</wcf:BaseClass>
</wcf:ClassesCollection>
</tem:composite>
</tem:GetDataUsingDataContract>
</soapenv:Body>
</soapenv:Envelope>
And this is how my DataContracts looks like:
[DataContract]
public class MyDataContract
{
public MyDataContract()
{
ClassesCollection = new Collection<BaseClass>();
}
[DataMember]
public Collection<BaseClass> ClassesCollection { get; private set; }
}
[DataContract]
[KnownType(typeof(ClassA))]
public abstract class BaseClass
{
[DataMember]
public int Id { get; set; }
}
[DataContract]
public class ClassA : BaseClass
{
[DataMember]
public int Name { get; set; }
}
So what should my request looks like? Or need I add some other attribute to DataContract?
First make sure that your collection has a public setter, otherwise WCF won't be able to deserialize it:
[DataMember]
public Collection<BaseClass> ClassesCollection { get; set; }
and then here's how a sample request might look like:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<GetDataUsingDataContract xmlns="http://tempuri.org/">
<composite xmlns:a="http://schemas.datacontract.org/2004/07/WcfService1" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:ClassesCollection>
<a:BaseClass i:type="a:ClassA">
<a:Id>1</a:Id>
<a:Name>5</a:Name>
</a:BaseClass>
</a:ClassesCollection>
</composite>
</GetDataUsingDataContract>
</s:Body>
</s:Envelope>