You need to put the KnownTypeAttribute
on your IMessage
implementations:
public interface IMessage
{
string Content { get; }
}
[KnownType(typeof(Message))]
public class Message : IMessage {
public string Content{ get; set; }
}
[KnownType(typeof(Message2))]
public class Message2 : IMessage
{
public string Content { get; set; }
}
So when calling the following action:
public IEnumerable<IMessage> Get()
{
return new IMessage[] { new Message { Content = "value1" },
new Message2 { Content = "value2" } };
}
The result will be this:
<ArrayOfanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<anyType xmlns:d2p1="http://schemas.datacontract.org/2004/07/MvcApplication3.Controllers" i:type="d2p1:Message">
<d2p1:Content>value1</d2p1:Content>
</anyType>
<anyType xmlns:d2p1="http://schemas.datacontract.org/2004/07/MvcApplication3.Controllers" i:type="d2p1:Message2">
<d2p1:Content>value2</d2p1:Content>
</anyType>
</ArrayOfanyType>
But this will only work one "way". So you cannot post back the same XML.
In order to the following action should work:
public string Post(IEnumerable<IMessage> messages)
You need to register the known types globally, with configuring a DataContractSerializer
and setting up in the GlobalConfiguration.Configuration.Formatters
GlobalConfiguration.Configuration
.Formatters
.XmlFormatter.SetSerializer<IEnumerable<IMessage>>(
new DataContractSerializer(typeof(IEnumerable<IMessage>),
new[] { typeof(Message), typeof(Message2) }));
With using the configuration you don't need the KnownTypeAttribute
on your implementation types.