如何在使用ASP.NET MVC Web API时注册已知类型以进行序列化

Ale*_*sev 7 c# asp.net-mvc datacontractserializer asp.net-web-api

我有一个返回的ASP.NET MVC Web API控制器 public IEnumerable<IMessage> Get()

它抛出异常,我需要注册从IMessage传递给已知类型集合派生的类型DataContractSerializer.

如何注册"已知类型"为使用DataContractSerializerDataContractJSONSerializer在MVC的Web API项目?

KnownType属性不能放在接口上.

nem*_*esv 7

你需要把KnownTypeAttribute你的IMessage实现:

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; }
}
Run Code Online (Sandbox Code Playgroud)

因此,在调用以下操作时:

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

结果将是这样的:

<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>
Run Code Online (Sandbox Code Playgroud)

但这只会有一种"方式".所以你不能回发相同的XML.

为了以下行动应该工作:

public string Post(IEnumerable<IMessage> messages)
Run Code Online (Sandbox Code Playgroud)

您需要在全局中注册已知类型,并在中配置DataContractSerializer和设置GlobalConfiguration.Configuration.Formatters

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

使用配置时,您不需要KnownTypeAttribute实现类型.