2013-08-19 40 views
5

Tôi đang cố gắng ràng buộc một hành động điều khiển với một giao diện nhưng vẫn duy trì hành vi ràng buộc mặc định.mô hình api web ràng buộc với một giao diện

public class CoolClass : ISomeInterface 
{ 
    public DoSomething {get;set;} // ISomeInterface 
} 

public class DosomethingController : ApiController 
{ 
    public HttpResponseMessage Post(ISomeInterface model) 
    { 
     // do something with model which should be an instance of CoolClass 
    } 
} 

Người tiêu dùng dịch vụ của tôi không biết gì về CoolClass để họ thêm "$ type" vào Json họ đang chuyển sẽ là ý kiến ​​của tôi. Tôi muốn có thể xử lý nó trong dịch vụ. Nếu tôi chỉ định CoolClass làm tham số hành động thì nó hoạt động tốt.

EDIT: Vì vậy, tôi tìm thấy một giải pháp một phần cho câu hỏi của tôi ở đây Dependency injection for ASP.NET Web API action method parameters nhưng có một vấn đề tiếp theo. Giải pháp đó không giải quyết các thuộc tính giao diện. Xem ví dụ của tôi dưới đây.

IConcreteClass sẽ được giải quyết, nhưng ISubtype sẽ không.

public class SubConcreteClass : ISubtype 
{ 
    // properties 
} 

public class ConcreteClass : IConcreteClass 
{ 
    public ISubtype Subtype {get;set;} 
} 

Khi trình định dạng phương tiện truyền thông thấy rằng có thể giải quyết loại trong IConcreteClass, sau đó đọc toàn bộ luồng. Vì vậy, tôi đoán không có cơ hội để giải quyết các thành viên giao diện.

+0

Đối với lựa chọn khác, hãy kiểm tra câu trả lời của tôi đến một câu hỏi tương tự [_here_] (http: // stackoverflow.com/questions/14124189/can-i-pass-an-interface-based-object-to-an-mvc-4-webapi-post/22279204#22279204). –

Trả lời

11

Vì vậy, trong trường hợp điều này có thể giúp bất kỳ ai khác, tôi sẽ tiếp tục và đăng giải pháp mà tôi đã đưa ra.

Như tôi đã đề cập ở trên, các tham số giao diện của phương thức hành động có thể được giải quyết bằng DI. Nhưng các thành viên giao diện của đối tượng đó cần phải được xử lý khác nhau.

Tôi đã tạo 2 loại trình biến đổi Json, một loại thực thể duy nhất và một loại bộ sưu tập, để trang trí các thuộc tính giao diện.

Đây là lớp cần được giải quyết dưới dạng thông số giao diện hành động.

public class CreateEnvelopeModel : ICreateEnvelopeCommand 
{ 
    [JsonConverter(typeof(EntityModelConverter<CreateEmailModel, ICreateEmailCommand>))] 
    public ICreateEmailCommand Email { get; set; } 
    [JsonConverter(typeof(CollectionEntityConverter<CreateFormModel, ICreateFormCommand>))] 
    public IList<ICreateFormCommand> Forms { get; set; } 
} 

Dưới đây là phương pháp hành động điều khiển

public HttpResponseMessage PostEnvelope(ICreateEnvelopeCommand model) 
{ 
    // do stuff 
} 

Đây là bộ chuyển đổi 2 json

public class EntityModelConverter<T, Tt> : JsonConverter where T : Tt 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return (objectType == typeof(Tt)); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     return serializer.Deserialize<T>(reader); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     serializer.Serialize(writer, value, typeof(T)); 
    } 
} 

public class CollectionEntityConverter<T, Tt> : JsonConverter where T : Tt 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return (objectType == typeof(IList<Tt>)); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     IList<Tt> items = serializer.Deserialize<List<T>>(reader).Cast<Tt>().ToList(); 
     return items; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     serializer.Serialize(writer, value, typeof(IList<T>)); 
    } 
} 
+0

Đây là một giải pháp tuyệt vời. – saille

+0

Bạn là người giỏi nhất, nó hoạt động hoàn hảo. – alsafoo

+0

Điều này thật đơn giản và hiệu quả. Có bất kỳ hạn chế nào trong việc sử dụng liên kết mô hình tùy chỉnh này hay không? Bất kỳ suy nghĩ nào về cách sử dụng thứ gì đó như thế này trên bộ sưu tập nơi giao diện có nhiều lớp triển khai (ví dụ: IAuto, Ô tô: IAuto, Xe tải: IAuto)? – BrianS

-1

Nhìn vào Model Binders phần here. Tôi nghĩ đó là trường hợp của bạn.

+0

Cảm ơn Alex. Tôi thấy trang đó nhưng tôi đã thực sự hy vọng điều này có thể được giải quyết với thùng chứa DI của tôi. Không thể giải quyết các tham số giao diện hành động API với DI? – chrisl91

+0

Đã cập nhật câu hỏi của tôi. – chrisl91

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