How to register known types for serialization using ASP.NET MVC Web API

I have an ASP.NET MVC Web API that returns public IEnumerable<IMessage> Get()

It throws an exception that I need to register types that come from IMessage in a collection of known types passed to the DataContractSerializer .

How to register Known Types for use with the DataContractSerializer and DataContractJSONSerializer in an MVC Web API project?

The KnownType attribute cannot be placed on an interface.

+6
source share
1 answer

You need to put KnownTypeAttribute in 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, calling the following action:

  public IEnumerable<IMessage> Get() { return new IMessage[] { new Message { Content = "value1" }, new Message2 { Content = "value2" } }; } 

The result will be like 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 "path". Thus, you cannot send back the same XML.

In order for the following action to work:

 public string Post(IEnumerable<IMessage> messages) 

You need to register known types around the world, with the DataContractSerializer set up and set up in GlobalConfiguration.Configuration.Formatters

 GlobalConfiguration.Configuration .Formatters .XmlFormatter.SetSerializer<IEnumerable<IMessage>>( new DataContractSerializer(typeof(IEnumerable<IMessage>), new[] { typeof(Message), typeof(Message2) })); 

When using the configuration, you do not need KnownTypeAttribute for your implementation types.

+7
source

All Articles