2013-01-25 60 views
6

我有一個返回ASP.NET MVC的Web API控制器後,註冊序列已知類型public IEnumerable<IMessage> Get()如何使用ASP.NET MVC的Web API

它拋出異常,我需要註冊,從IMessage在已知的派生類型類型集合傳遞給DataContractSerializer

如何在MVC Web API項目中使用DataContractSerializerDataContractJSONSerializer註冊「已知類型」?

KnownType屬性不能放在接口上。

回答

7

你需要把KnownTypeAttributeIMessage實現:

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; } 
} 

於是致電以下操作時:

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

其結果將是這樣的:

<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> 

但是這隻能用一種「方式」。所以你不能回發相同的XML。

爲了下面的行動應該工作:

public string Post(IEnumerable<IMessage> messages) 

您需要在全球範圍內註冊的已知類型,具有配置DataContractSerializer,並在GlobalConfiguration.Configuration.Formatters

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

建立與使用配置您的實施類型不需要KnownTypeAttribute

+0

咦?把[KnownType(Type)]放在一個Type本身看起來很奇怪,但我試了一下。 –

+0

奇怪,但它確實有效,但只在一面。我有一個公共無效Post([FromBody] IEnumerable 消息)方法,然後我通過流,消息總是空的,我用這個提琴手也許我的帖子查詢不正確,或者序列化程序無法讀取它中寫道。 –

+0

是的,當你回發相同的XML時,它不工作。我猜是因爲'ArrayOfanyType'和'anyType'。我現在擺弄它。如果我找到了某些東西,我會盡快回復您。 – nemesv