C# 使用自定义转换器反序列化抽象类集合

C# 使用自定义转换器反序列化抽象类集合,c#,json.net,deserialization,abstract-class,C#,Json.net,Deserialization,Abstract Class,目前,我们正在尝试反序列化包含抽象类ICollection的json字符串。在做了一些研究之后,我决定使用转换器,但我似乎仍然无法克服以下错误: 无法创建WorkflowActivity类型的实例。类型是接口或抽象类,无法实例化。“路径”活动[0]。控制器名称 这是我正在使用的代码: var jsonString = "{\"activities\":[{\"controllerName\":\"index\",\"actionName\":\"Index\",\"routeVa

目前,我们正在尝试反序列化包含抽象类ICollection的json字符串。在做了一些研究之后,我决定使用转换器,但我似乎仍然无法克服以下错误:

无法创建WorkflowActivity类型的实例。类型是接口或抽象类,无法实例化。“路径”活动[0]。控制器名称

这是我正在使用的代码:

        var jsonString = "{\"activities\":[{\"controllerName\":\"index\",\"actionName\":\"Index\",\"routeValueByName\":{},\"key\":\"9a9c50c5-ae82-40be-89dc-e9676cf731fb\",\"OwnerUserId\":\"ff9f2cfe-5523-4844-bc97-f705f40de2f5\",\"nextActivityChooserType\":\"FieldComparisonActivityChooser\",\"nextActivityChooserConfig\":\"{\"expressions\":[{\"code\":\"wfQuestion.Valid == true\",\"workflowActivityKey\":\"B1\"},{\"code\":\"wfQuestion.Valid == false\",\"workflowActivityKey\":\"B2\"}]}\",\"emailTemplateId\":1},{\"controllerName\":\"index\",\"actionName\":\"Index\",\"routeValueByName\":{},\"key\":\"B1\",\"OwnerUserId\":\"9a9c50c5-ae82-40be-89dc-e9676cf731fb\",\"nextActivityChooserType\":\"FieldComparisonActivityChooser\",\"nextActivityChooserConfig\":\"{\"expressions\":[{\"code\":\"wfQuestion.Valid == true\",\"workflowActivityKey\":\"B1\"},{\"code\":\"wfQuestion.Valid == false\",\"workflowActivityKey\":\"B2\"}]}\",\"emailTemplateId\":1},{\"controllerName\":\"index\",\"actionN\r\name\":\"Index\",\"routeValueByName\":{},\"key\":\"B2\",\"OwnerUserId\":\"00188258-4467-484f-8c59-8e0da3e991f1\",\"nextActivityChooserType\":\"FieldComparisonActivityChooser\",\"nextActivityChooserConfig\":\"\",\"emailTemplateId\":1}]}";
        var deserialized = WorkflowDescription.Deserialize(jsonString);
WorkflowDescription类:

internal class WorkflowDescription : IWorkflowDescription
{
    public string ToJson()
    {
        return JsonConvert.SerializeObject(this);
    }

    public static WorkflowDescription Deserialize(string json)
    {
        return JsonConvert.DeserializeObject<WorkflowDescription>(json, new WorkflowDescriptionConverter(typeof(WorkflowDescription), typeof(ICollection<WorkflowActivity>), typeof(WorkflowActivity)));
    }
    //this is the collection of abstract class I am having trouble with
    [JsonProperty("activities")]
    public ICollection<WorkflowActivity> Activities { get; set; }
}
WebActionWorkflowActivity类。(这是我试图在转换器中转换的内容)

公共类WebActionWorkflowActivity:WorkflowActivity
{
[JsonProperty(“controllerName”)]
公共字符串控制器名称{get;set;}
[JsonProperty(“actionName”)]
公共字符串ActionName{get;set;}
[JsonProperty(“routeValueByName”)]
公共IDictionary RouteValueByName{get;set;}
}
WorkflowDescriptionConverter类*注:目前我并不十分关心ReadJson和WriteJson中的情况。我已经在那里放置了断点,因为现在我只是想看看我是否可以使用这些方法,并且在我通过上面的错误后将进行优化

 public class WorkflowDescriptionConverter : JsonConverter
{
    private readonly Type[] _types;
    public WorkflowDescriptionConverter(params Type[] types)
    {
        _types = types;
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        JToken t = JToken.FromObject(value);
        JObject jo = (JObject)t;
        List<WorkflowActivity> convertedActivities = new List<WorkflowActivity>();
        foreach (var activity in jo["activities"])
        {
            if (activity.GetType().GetProperty("controllerName") != null)
            {
                convertedActivities.Add(new WebActionWorkflowActivity
                {
                    ActionName = activity["actionName"].ToString(),
                    ControllerName = activity["controllerName"].ToString()
                });
            }
        }


        jo.WriteTo(writer);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();

    }

    public override bool CanConvert(Type objectType)
    {
        return _types.Any(t => t == objectType);
    }

    public override bool CanRead
    {
        get { return false; }
    }

    public override bool CanWrite
    { get { return true; } }
}
}
公共类WorkflowDescriptionConverter:JsonConverter
{
私有只读类型[]\u类型;
公共工作流描述转换器(参数类型[]类型)
{
_类型=类型;
}
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
JToken t=JToken.FromObject(值);
JObject jo=(JObject)t;
List convertedActivities=新列表();
foreach(jo[“活动”]中的var活动)
{
if(activity.GetType().GetProperty(“controllerName”)!=null)
{
convertedActivities.Add(新建WebActionWorkflowActivity
{
ActionName=活动[“ActionName”]。ToString(),
ControllerName=activity[“ControllerName”].ToString()
});
}
}
写作工作(作家);
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
抛出新的NotImplementedException();
}
公共覆盖布尔CanConvert(类型objectType)
{
返回_types.Any(t=>t==objectType);
}
公共覆盖布尔可读取
{
获取{return false;}
}
公共覆盖布尔可写
{get{return true;}}
}
}

对于传入的所有类型,我能够确认CanConvert在我的转换器中确实返回true。谢谢

这似乎是您自己实现的最终答案:返回false,因此当然不会调用转换器的
ReadJson()
。有关您似乎想做的事情的示例,请参见或。
public abstract class WorkflowActivity
{
    [JsonProperty("key")]
    public string WorkflowActivityKey { get; set; }
    [JsonProperty("OwnerUserId")]
    public string OwnerUserId { get; set; }

    [JsonIgnore]
    public Type NextActivityChooserType
    {
        get { return Type.GetType(NextActivityChooserTypeName); }
    }

    [JsonProperty("nextActivityChooserType")]
    public string NextActivityChooserTypeName { get; set; }

    [JsonProperty("nextActivityChooserConfig")]
    public string NextActivityChooserConfig { get; set; }

    [JsonProperty("emailTemplateId")]
    public int EmailTemplateId { get; set; }


}
 public class WebActionWorkflowActivity : WorkflowActivity
{
    [JsonProperty("controllerName")]
    public string ControllerName { get; set; }

    [JsonProperty("actionName")]
    public string ActionName { get; set; }

    [JsonProperty("routeValueByName")]
    public IDictionary<string, object> RouteValueByName { get; set; }
}
 public class WorkflowDescriptionConverter : JsonConverter
{
    private readonly Type[] _types;
    public WorkflowDescriptionConverter(params Type[] types)
    {
        _types = types;
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        JToken t = JToken.FromObject(value);
        JObject jo = (JObject)t;
        List<WorkflowActivity> convertedActivities = new List<WorkflowActivity>();
        foreach (var activity in jo["activities"])
        {
            if (activity.GetType().GetProperty("controllerName") != null)
            {
                convertedActivities.Add(new WebActionWorkflowActivity
                {
                    ActionName = activity["actionName"].ToString(),
                    ControllerName = activity["controllerName"].ToString()
                });
            }
        }


        jo.WriteTo(writer);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();

    }

    public override bool CanConvert(Type objectType)
    {
        return _types.Any(t => t == objectType);
    }

    public override bool CanRead
    {
        get { return false; }
    }

    public override bool CanWrite
    { get { return true; } }
}
}