首页 文章

将Json JObject转换为派生类

提问于
浏览
0

我有一个名为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'派生的任何 dynamic 类型,但我无法获取派生类型 .

1 回答

  • 0

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

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

    因为 abstract 类无法实例化(解串器在概念上需要"new up"一个对象,然后将JSON属性复制到其中),所以你只需要将它填入 ProcessConfigurations 类中 .

    所以,你可以做什么?

    直接的答案是在序列化的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” .

    如果你没有内置的方法来执行此操作,则必须将类型信息存储在您自己的字段中,并编写自定义的 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;
        }
    }
    

相关问题