2017-02-22 72 views
0

我有一个接口和两个类来实现它。从客户端发送接口实现为json的麻烦

namespace FirebaseNet.Messaging 
{ 
    public interface INotification 
    { 
     string Title { get; set; } 
    } 

    public class AndroidNotification : INotification 
    { 
     public string Title { get; set; } 
    } 

    public class IOSNotification : INotification 
    { 
     public string Title { get; set; } 
    } 
} 

现在我又有了这样的课。

public class Message 
{ 
    public INotification Notification { get; set; } 
} 

消息参数传递给类这样

[HttpPost] 
public async Task<JsonResult> SendMessage(Message message) 

此参数可以是

var message = new Message() 
{ 
    Notification = new AndroidNotification() 
    { 
     Title = "Portugal vs. Denmark" 
    } 
}; 

var message = new Message() 
{ 
    Notification = new IOSNotification() 
    { 
     Title = "Portugal vs. Denmark" 
    } 
}; 

到目前为止,所有的作品。现在我想要AJAX POST到SendMessage。我尝试过使用这个DTO。

JavaScript代码

var message = { 
    Notification : { 
     Title : "Portugal vs. Denmark" 
    } 
}; 

这显然与

失败无法创建接口的实例。

什么是它的理想解决方法?

P.S:改变Message类的思想,以

public class Message 
{ 
    public INotification Notification { get; set; } 
    public AndroidNotification AndroidNotification { get; set; } 
    public IOSNotification IOSNotification { get; set; } 
} 

这是一个第三方的DLL,我不想碰它理想。为实现这一

回答

2

一种方法是编写自定义的模型绑定:

public class NotificationModelBinder : DefaultModelBinder 
{ 
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) 
    { 
     var typeValue = bindingContext.ValueProvider.GetValue("ModelType"); 
     var type = Type.GetType(
      (string)typeValue.ConvertTo(typeof(string)), 
      true 
     ); 

     if (!typeof(INotification).IsAssignableFrom(type)) 
     { 
      throw new InvalidOperationException("Bad Type"); 
     } 

     var model = Activator.CreateInstance(type); 
     bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, type); 
     return model; 
    } 
} 

自举应用程序时,你会登记:

ModelBinders.Binders.Add(
    typeof(INotification), 
    new NotificationModelBinder() 
); 

现在这将允许客户指定通知的具体类型:

var message = { 
    ModelType: "WebApplication1.Models.AndroidNotification", 
    Notification : { 
     Title : "Portugal vs. Denmark" 
    } 
}; 

或者:

var message = { 
    ModelType: "WebApplication1.Models.IOSNotification", 
    Notification : { 
     Title : "Portugal vs. Denmark" 
    } 
}; 

当然,您可以调整模型联编程序的确切属性名称,以指示具体类型和可能的值。在我的示例中,应该使用完全限定类型名称,但可以使用更友好的名称进行映射。

+0

我有在'WebApp1'中引用的项目'p1.FirebaseNet'。我在json调用中尝试了'p1.FirebaseNet.Messaging.AndroidNotification'(以及'FirebaseNet.Messaging.AndroidNotification')作为'ModelType'。它失败了,例外''无法从程序集'WebApp1,Version ...'加载类型'p1.FirebaseNet.Messaging.AndroidNotification''我可能做错了什么? – naveen