目前,我们正在尝试反序列化包含抽象类的ICollection的json字符串。在做了一些研究后,我决定使用转换器,但我似乎仍然无法通过以下错误:
无法创建WorkflowActivity类型的实例。 Type是接口或抽象类,无法实例化。路径'活动[0] .controllerName
这是我正在使用的代码:
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; }
}
WorkflowDescription接口:
public interface IWorkflowDescription
{
ICollection<WorkflowActivity> Activities { get; set; }
}
WorkflowActivity基类:
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; }
}
WebActionWorkflowActivity类。 (这是我想在转换器中转换的内容)
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; }
}
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; } }
}
}
我能够确认CanConvert确实在我的转换器中为所有传入的类型返回true。谢谢!