简体   繁体   English

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

[英]How to register Known Types for serialization when using ASP.NET MVC Web API

I have a ASP.NET MVC Web API controller that returns public IEnumerable<IMessage> Get() 我有一个ASP.NET MVC Web API控制器,它返回public IEnumerable<IMessage> Get()

It throws exception that I need to register types that derive from IMessage in known types collection passed to DataContractSerializer . 它抛出异常,我需要在传递给DataContractSerializer已知类型集合中注册从IMessage派生的类型。

How to register "Known Types" for using with DataContractSerializer and DataContractJSONSerializer in MVC Web API project? 如何在MVC Web API项目中注册“已知类型”以与DataContractSerializerDataContractJSONSerializer一起使用?

KnownType attribute cannot be placed on interface. KnownType属性不能放在接口上。

You need to put the KnownTypeAttribute on your IMessage implementations: 您需要在您的IMessage实现上放置KnownTypeAttribute

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. 所以你不能回发相同的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 您需要全局注册已知类型,配置DataContractSerializer并在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. 使用配置时,您不需要实现类型的KnownTypeAttribute

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM