我有一个接口和两个实现它的类。
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; }
}
Message参数传递给类
的类[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,我不想理想地触摸它。
答案 0 :(得分: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"
}
};
当然,您可以调整模型绑定器以获取指示具体类型和可能值的确切属性名称。在我的示例中,应该使用完全限定的类型名称,但是您可以使用更友好的名称进行映射。