我有一个名为NProcess的抽象类,我将从中派生出许多不同的Process对象。
public abstract class NProcess
{
public ProcessConfigurations ProcessSettings { get; set; }
}
ProcessessConfigutations类如下所示:
[Browsable(true)]
public abstract class ProcessConfigurations { }
从NProcess派生的对象示例是EmailReader, FileCopier or FTPProcess
,....可以是任何内容,因此从ProcessConfigurations派生的属性类将具有一组仅与该过程相关的属性。
我可以使用Reflection加载从Nprocess
派生的进程,当我选择一个属性网格中出现一组不同的属性时,如预期的那样。
我正在序列化设置并将它们作为BSON存储在数据库中。
问题:反序列化向我显示了Json字符串,但是我收到以下错误:
无法隐式转换类型' Newtonsoft.Json.Linq.JObject'至 ' ProcessConfigurations'
我需要能够将JObject转换或转换为任何动态类型派生自' ProcessConfigurations'但我无法得到派生类型。
答案 0 :(得分:0)
如果每个配置都是不同的类,您如何知道它们从数据库出来时应该是什么类型?假设您查询数据库并返回
{ "SourceFullPath": "c\\Source", "Destination": "c:\\temp", "OnExists": 1 }
您不知道应该反序列化的具体类型。并且您不能将它填充到ProcessConfigurations
类中,因为abstract
类无法实例化(解串器将在概念上需要" new up"一个对象然后复制将JSON属性放入其中)。
那你能做什么?
直接的答案是在序列化的Json中包含类型信息。 Json.Net有一个功能,它会自动为您执行此操作。它被称为TypeNameHandling。由此产生的Json看起来像:
{ "$type": "Your.Namespace.Here.MyConcreteProcessConfiguration, Your.Assembly.Here", "SourceFullPath": "c\\Source", "Destination": "c:\\temp", "OnExists": 1 }
然后,当它被反序列化时,Json.Net会知道哪个类型为" new up"。
如果您不想使用Json.Net内置的方式执行此操作,则必须将类型信息存储在您自己的字段中并编写自定义JsonConverter
正如@JDB链接中提到的那样:JSON.NET deserialize to abstract class or interface。 JsonConverter
基本上会做这样的事情来反序列化(取自上面的博客文章):
public class MyConverter : JsonConverter {
// ... other stuff, see the blog article
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
if (jo["MyCustomType"].Value<string>() == "MyConcreteProcessConfiguration")
return jo.ToObject<MyConcreteProcessConfiguration>(serializer);
if (jo["MyCustomType"].Value<string>() == "MyOtherConcreteProcessConfiguration")
return jo.ToObject<MyOtherConcreteProcessConfiguration>(serializer);
return null;
}
}