Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Json反序列化以接口作为属性的复杂对象_C#_Json_Asp.net Web Api_Json.net - Fatal编程技术网

C# Json反序列化以接口作为属性的复杂对象

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

我们正在使用.NET4.6构建一个WebAPI应用程序 我们正在尝试将JsonConvert.DeserializeObject转换为复杂对象。这个对象有一个复杂对象的列表,其中有一个接口。 所以我们有一个Task类,它有一个TaskDetails列表,该类有一个IBehavior属性

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());