将Json JObject转换为派生类



我有一个名为NProcess的抽象类,我将从中派生出许多不同的Process对象。

public abstract class NProcess
{   
    public ProcessConfigurations ProcessSettings { get; set; } 
}

processessconfigurations类如下:

[Browsable(true)]
public abstract class ProcessConfigurations { }

从NProcess派生的对象示例有EmailReader, FileCopier or FTPProcess,....可以是任何东西,因此从ProcessConfigurations派生的属性类将具有一组仅与流程相关的属性。

我能够使用Reflection加载从Nprocess派生的进程,当我选择一个时,一组不同的属性出现在属性网格中,如预期的那样。

我正在序列化设置并将它们作为BSON存储在数据库中。

问题:反序列化显示了Json字符串,但我得到以下错误:

不能隐式转换"Newtonsoft.Json.Linq"类型。JObject"ProcessConfigurations"

我需要能够将jobobject强制转换或转换为任何动态类型派生自'ProcessConfigurations',但我无法获得派生类型。

如果每个配置都是不同的类,那么当它们从数据库中出来时,您如何知道它们应该是什么类型?假设您查询数据库并返回

{ "SourceFullPath": "c\Source", "Destination": "c:\temp", "OnExists": 1 }

你不知道它应该被反序列化成什么具体类型。而且你不能把它塞进ProcessConfigurations类,因为abstract类不能被实例化(反序列化器在概念上需要"新建"一个对象,然后将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。要做到这一点,您必须将类型信息存储在您自己的字段中,并编写一个自定义JsonConverter,如@ jdbc: JSON链接中提到的那样。NET反序列化为抽象类或接口。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;
    }
}