2013-01-25 26 views
6

Tôi có một ASP.NET MVC điều khiển Web API trả về public IEnumerable<IMessage> Get()Làm thế nào để đăng ký các loại Được biết đến với serialization khi sử dụng ASP.NET MVC Web API

Nó ném ngoại lệ mà tôi cần phải đăng ký loại mà bắt nguồn từ IMessage trong biết các loại bộ sưu tập được chuyển đến DataContractSerializer.

Cách đăng ký "Các loại đã biết" để sử dụng với DataContractSerializerDataContractJSONSerializer trong dự án API MVC Web API?

Thuộc tính KnownType không thể được đặt trên giao diện.

Trả lời

7

Bạn cần phải đặt các KnownTypeAttribute trên IMessage triển khai của bạn:

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

Vì vậy, khi gọi hành động sau đây:

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

Kết quả sẽ là thế này:

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

Nhưng điều này sẽ chỉ làm việc một "cách". Vì vậy, bạn không thể đăng lại cùng một XML.

Để hành động sau đây nên làm việc:

public string Post(IEnumerable<IMessage> messages) 

Bạn cần phải đăng ký các loại được biết đến trên toàn cầu, với cấu hình DataContractSerializer và thiết lập trong GlobalConfiguration.Configuration.Formatters

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

Với việc sử dụng các cấu hình bạn không cần KnownTypeAttribute về các loại triển khai của mình.

+0

Huh? đặt [KnownType (Type)] vào một Type có vẻ lạ đối với tôi, nhưng tôi thử nó. –

+0

Lạ, nhưng nó thực sự hoạt động nhưng chỉ ở một bên. Tôi có một public void Post ([FromBody] IEnumerable tin nhắn) phương pháp mà sau đó tôi vượt qua dòng, và tin nhắn luôn luôn null, tôi đang sử dụng Fiddler cho điều này có thể đăng bài của tôi là không chính xác, hoặc serializer không thể đọc những gì nó đã viết. –

+0

Vâng, nó không hoạt động khi bạn đăng lại cùng một xml. Tôi đoán vì 'ArrayOfanyType' và' anyType'. Tôi hiện đang không hài lòng với nó. Tôi sẽ lấy lại cho bạn nếu tôi tìm thấy một cái gì đó. – nemesv

Các vấn đề liên quan