2013-01-25 15 views
6

Mam kontroler Web API ASP.NET MVC, która zwraca public IEnumerable<IMessage> Get()Jak zarejestrować znanych typów dla serializacji przy użyciu ASP.NET MVC Web API

To rzuca wyjątek, że muszę się zarejestrować typy, które wynikają z IMessage w znany kolekcja typów przeszła na DataContractSerializer.

Jak zarejestrować "Znane typy" do używania z DataContractSerializer i DataContractJSONSerializer w projekcie MVC Web API?

Atrybutu KnownType nie można umieścić w interfejsie.

Odpowiedz

7

Trzeba umieścić KnownTypeAttribute na swoich implementacjach 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; } 
} 

więc podczas wywoływania następujące działania:

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

wynik będzie tak:

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

Ale to zadziała tylko w jeden "sposób". Więc nie możesz przesłać tego samego pliku XML.

W celu poniższego działania powinno działać:

public string Post(IEnumerable<IMessage> messages) 

Musisz zarejestrować znane typy globalnie, z konfigurowania DataContractSerializer i utworzenie w GlobalConfiguration.Configuration.Formatters

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

Z pomocą konfiguracji nie potrzebujesz KnownTypeAttribute dla twoich typów implementacji.

+0

Huh? Umieszczenie [KnownType (Type)] na samym typie wydaje mi się dziwne, ale spróbuję. –

+0

Dziwne, ale działa naprawdę, ale tylko w jedną stronę. Mam public void Post ([FromBody] IEnumerable messages) metodę, do której następnie przesyłam strumień, a wiadomości zawsze są puste, używam Fiddlera, może to moje zapytanie pocztowe jest niepoprawne, lub serializator nie może odczytać, co to jest napisał. –

+0

Tak, to nie działa po ponownym przesłaniu tego samego xml. Chyba ze względu na 'ArrayOfanyType' i' anyType'. W tej chwili mam do czynienia z tym. Wrócę do ciebie, jeśli coś znajdę. – nemesv

Powiązane problemy