2012-12-19 8 views
5

Giả sử tôi có một mô hình:Làm thế nào để đăng bài trong ASP.NET Web API với bất động sản mô hình như giao diện

public class Menu 
{ 
    public string Name { get; set; } 
    public IMenuCommand Next { get; set; } 
} 

IMenuCommand có thể có hiện thực khác nhau, như:

public class NextStepCommand : IMenuCommand 
{ 
    public int Step { get; set; } 
} 

public class VoiceCommand : IMenuCommand 
{ 
    public string Message { get; set; } 
} 

Và tôi muốn POST các menu với các lệnh khác nhau cho dịch vụ ASP.NET Web API. Làm thế nào tôi có thể làm điều đó?

Các yêu cầu dưới đây sẽ tạo ra một đối tượng với quy định Name, nhưng Next lệnh sẽ được null:

POST http://localhost/api/menus: {"name":"bob","next":{"step":1}} 
Returns 201: {"Name":"bob","Next":null} 

Default Web chất kết dính API không thể ánh xạ params yêu cầu của tôi với C# loại cần thiết - dĩ nhiên đó là một phần khó khăn. Tôi có thể sử dụng một số thuộc tính "kiểu đã biết" cho các thuộc tính dựa trên giao diện hoặc có cách tiếp cận nào khác để xử lý trường hợp này, có thể là một trình kết nối mô hình tùy chỉnh?

Trả lời

5

Tôi nghĩ rằng những gì bạn đang tìm kiếm là sự hỗ trợ của Json.NET để xử lý tên loại. Nó cho phép bạn chỉ định loại để deserialize vào bằng cách thêm thẻ "$ type" json. Bạn có thể thử mã này ra để xem cách nó hoạt động:

Console.WriteLine(JsonConvert.DeserializeObject<Menu>(
    @"{ 
     ""name"":""bob"", 
     ""next"": 
     { 
      ""$type"" : ""ConsoleApplication.NextStepCommand,ConsoleApplication"", 
      ""step"" : 1 
     } 
    }", 
    new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto }).Next); 

Bạn sẽ phải thay thế các namespace và lắp ráp tên với riêng bạn, nhưng bạn sẽ thấy NextStepCommand được deserialized một cách chính xác.

Trong WebAPI, bạn sẽ cần phải chỉnh yêu cầu của bạn để thêm "$ gõ" loại thông tin, và bạn sẽ cần phải kích hoạt TypeNameHandling như thế này:

config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto; 
+0

Làm việc đối với tôi khi tôi đặt 'TypeNameHandling .Auto' cho bộ nối tiếp JSON Web API và gửi một yêu cầu với "$ type" cần thiết của một lệnh. Nhưng tôi có thể bật tính năng 'TypeNameHandling' chỉ để deserialization? Bởi vì bây giờ tôi có quá nhiều rác trong đầu ra JSON trong các dịch vụ GET. – whyleee

+6

Tìm thấy rằng có thể sử dụng '[JsonProperty (TypeNameHandling = TypeNameHandling.All)]' cho các thuộc tính mô hình cụ thể (từ [Json.NET blog] (http://james.newtonking.com/archive/2010/08/13/ json-net-3-5-release-8-3-5-final.aspx)). Đã kiểm tra bằng API Web - nó hoạt động. Bây giờ tốt hơn nhiều. – whyleee

+0

@Youssef Moussaoui - Bất kỳ ý tưởng nào về câu hỏi này: http://stackoverflow.com/questions/20252027/json-net-web-api-serialization-with-derrived-inherited-types ... Không có bất kỳ may mắn nào với bất kỳ điều gì! – amcdnl