是否可以反序列化从Abstract Class继承的对象?
我有以下内容:
public abstract partial class Item
{
public Item() { }
public int ItemID { get; set; }
public Nullable<int> ObjectStateID { get; set; }
}
public abstract partial class Appointment : Item
{
public Appointment() { }
public string AppointmentDescription { get; set; }
}
public partial class AppointedActivity : Appointment
{
public Nullable<int> AppointedActivityID { get; set; }
}
public partial class AppointedDevice : Appointment
{
public Nullable<int> AppointedDeviceID { get; set; }
}
我有一个控制器应该POST Item
s:
public Item PostItem([FromBody]Item item)
{
// item is always null here.
return item;
}
我遇到的问题是,无论我的身体内容是什么,控制器中的项目始终为空。
发送到控制器的JSON示例:
{
"ObjectStateID": 1,
"AppointmentDescription": "test",
"AppointedActivityID": 90902 // Valid Activity ID.
}
我使用的是实体框架,我不确定该代码有什么问题。
谢谢!
答案 0 :(得分:1)
您不能将抽象类型作为默认模型绑定器的参数传递给控制器。因为模型绑定器在创建此参数的实例时会出错。
如果您想为此类型创建自己的自定义模型装订器;
public class ItemModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var values = (ValueProviderCollection) bindingContext.ValueProvider;
var itemId = (int) values.GetValue("ItemId").ConvertTo(typeof (int));
var objectStateId = (int?) values.GetValue("ObjectStateId").ConvertTo(typeof(int));
//Make desicion and create the real type instance Appointment, AppointedActivity or AppointedDevice
return (Item) new Appointment { ItemId= itemId, ObjectStateId = objectStateId };
}
}
在Global.asax;
ModelBinders.Binders.Add(new KeyValuePair<Type, IModelBinder>(typeof(Item), new ItemModelBinder()));
答案 1 :(得分:0)
我最终在this和this上建立了我的解决方案,并创建了一个使用Contract Resolver
的自定义ItemResolver
:
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject item = JObject.Load(reader);
switch ((ResourceKind)item["ResourceKind"].Value<int>())
{
case ResourceKind.ACTIVITY:
return item.ToObject<AppointedActivity>();
case ResourceKind.CONSUMABLE:
return item.ToObject<AppointedConsumable>();
case ResourceKind.DEVICE:
return item.ToObject<AppointedDevice>();
default:
throw new Exception("Invalid ResourceType");
}
}