C# Json反序列化以接口作为属性的复杂对象
我们正在使用.NET4.6构建一个WebAPI应用程序 我们正在尝试将JsonConvert.DeserializeObject转换为复杂对象。这个对象有一个复杂对象的列表,其中有一个接口。 所以我们有一个Task类,它有一个TaskDetails列表,该类有一个IBehavior属性C# Json反序列化以接口作为属性的复杂对象,c#,json,asp.net-web-api,json.net,C#,Json,Asp.net Web Api,Json.net,我们正在使用.NET4.6构建一个WebAPI应用程序 我们正在尝试将JsonConvert.DeserializeObject转换为复杂对象。这个对象有一个复杂对象的列表,其中有一个接口。 所以我们有一个Task类,它有一个TaskDetails列表,该类有一个IBehavior属性 public class Task { public int Id { get; set; } public int TaskTypeId { get; set; } //TYPE pu
public class Task
{
public int Id { get; set; }
public int TaskTypeId { get; set; } //TYPE
public List<TaskDetail> TaskDetails { get; set; }
}
public class TaskDetail
{
public int Id { get; set; }
public IBehavior Behavior { get; set; }
}
具体行为是
public class PartPick : IBehavior
{
public bool AllowMultiplePicks { get; set; }
public bool RunLightsOnly { get; set; }
public bool StandardLightMode { get; set; }
}
或
JSon有效负载是:
{
"id": 10000,
"name": "Attach Spoiler",
"taskTypeId": 1,
"behavior": {
"pSet": 1,
"rundownsRequired": 1,
"multiSpindleMask": 4,
"multiSpindleMaskString": "0010000000000000"
}
}
我得到以下错误:
“请求无效。”,“modelState”:{“task.taskDetails[0]。behavior.pSet”:[“无法创建Bl.Models.EPA.IBehavior类型的实例。type是接口或抽象类,无法实例化。路径'taskDetails[0]。behavior.pSet”
我试图创建一个JsonBodyModelbinder:IModelBinder
其中,要反序列化的方法是:
private static T DeserializeObjectFromJson(string json)
{
var binder = new TypeNameSerializationBinder("");
var obj = JsonConvert.DeserializeObject<T>(json, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
Binder = binder
});
return obj;
}
private static T反序列化ObjectFromJSON(字符串json)
{
var binder=新的TypeNameSerializationBinder(“”);
var obj=JsonConvert.DeserializeObject(json,新的JsonSerializerSettings
{
TypeNameHandling=TypeNameHandling.Auto,
活页夹=活页夹
});
返回obj;
}
并且在httpConfiguration中连接:
config.Services.Insert(typeof(ModelBinderProvider), 0,
new SimpleModelBinderProvider(typeof(IBehavior), new JsonBodyModelBinder<IBehavior>()));
config.Services.Insert(typeof(ModelBinderProvider),0,
新的SimpleModelBinderProvider(typeof(IBehavior),新的JsonBodyModelBinder());
我还尝试将以下属性置于TaskDetail中IBehavior的属性之上
[JsonConverter(typeof(JsonBodyModelBinder<IBehavior>))]
public IBehavior Behavior { get; set; }
[JsonConverter(typeof(JsonBodyModelBinder))]
公共IBehavior行为{get;set;}
我相信反序列化程序不知道将接口映射到什么,所以提供一点反序列化程序的提示就可以了
public class TaskDetail
{
TaskDetails(PartPick partPick)
{
Behavior = partPick;
}
TaskDetails(TorqueTool torqueTool)
{
Behavior = torqueTool;
}
public int Id { get; set; }
public IBehavior Behavior { get; set; }
}
我相信反序列化程序不知道将接口映射到什么,所以提供一点反序列化程序的提示就可以了
public class TaskDetail
{
TaskDetails(PartPick partPick)
{
Behavior = partPick;
}
TaskDetails(TorqueTool torqueTool)
{
Behavior = torqueTool;
}
public int Id { get; set; }
public IBehavior Behavior { get; set; }
}
基本上,他们建议传递实现这个IBehavior
接口的类的实例
public class TaskDetail
{
public TaskDetail(TorqueTool behavior){
Behavior = behavior;
}
public int Id { get; set; }
public IBehavior Behavior { get; set; }
}
基本上,他们建议传递实现这个IBehavior
接口的类的实例
public class TaskDetail
{
public TaskDetail(TorqueTool behavior){
Behavior = behavior;
}
public int Id { get; set; }
public IBehavior Behavior { get; set; }
}
如果您使用的是DataContractSerializer,则应使用该属性定义希望实现该接口的应用程序类型
public class TaskDetail
{
public TaskDetail(TorqueTool behavior){
Behavior = behavior;
}
public int Id { get; set; }
public IBehavior Behavior { get; set; }
}
如果您使用的是XML序列化程序,则需要为每个类型标记“XmlInclude”属性,如图所示。如果您使用的是DataContractSerializer,则应使用该属性定义希望实现该接口的应用程序类型
public class TaskDetail
{
public TaskDetail(TorqueTool behavior){
Behavior = behavior;
}
public int Id { get; set; }
public IBehavior Behavior { get; set; }
}
如果您使用的是XML序列化程序,则需要为每个类型使用“XmlInclude”属性对其进行标记,如图所示。事实证明,我可以将TaskDetail中的属性从IBehavior更改为dynamic,并且可以正常工作。然后,当我需要使用具体类型时,我有一个可以返回具体类型(即torqueTool)的工厂.到那时我能做到
JsonConvert.DeserializeObject<TorqueTool>(taskDetail.Behavior.ToString());
JsonConvert.DeserializeObject(taskDetail.Behavior.ToString());
事实证明,我可以将TaskDetail中的属性从IBehavior更改为dynamic,它可以工作。然后,当我需要使用具体类型时,我有一个工厂可以返回具体类型(即torqueTool)。此时我可以这样做
JsonConvert.DeserializeObject<TorqueTool>(taskDetail.Behavior.ToString());
JsonConvert.DeserializeObject(taskDetail.Behavior.ToString());