使用Json.Net反序列化,将子对象反序列化为包含json的字符串/类似字符串? [英] Deserializing with Json.Net, deserialize sub-object into string/similar holding the json?
问题描述
我正在尝试使用Json创建一个配置文件,该文件将保存各种对象的配置.
I am trying to create a configuration file using Json that will hold configuration for various types of objects.
考虑此文件:
{
"cameras": [
{
"type": "Some.Namespace.CameraClass",
"assembly": "Some.Assembly",
"configuration": {
"ip": "127.0.0.1",
"port": 8080
}
}
]
}
在运行时,我将使用"type"和"assembly"这两个属性来构造一个支持特定接口的对象,然后将配置加载到该对象中.
At runtime I will use the two "type" and "assembly" properties to construct an object supporting a specific interface, and then I would like to load the configuration into that object.
但是,在编译时,我不知道配置"将映射到的类型.我想将其保留为json属性",并将其输入到camera对象中,然后让该对象将json反序列化为正确的类型.
However, at compile time I do not know the type that "configuration" would map to. I would like to retain it as a json "property" and feed that into the camera object, and then let that object deserialize the json into the right type.
因此,我想将包含特定摄像机类型的配置的配置文件部分随身带入对象本身,并让其处理,在携带时将其像黑匣子一样对待像那样.应该保留该部分的结构,因为在为每个相机实现创建配置类型时,我希望完全保真,甚至在必要时添加子对象.
As such I would like to just "carry" the part of the configuration file containing configuration for a particular camera type with me into the object itself, and let it deal with it, treating it like a black box while I carry it like that. The structure of that part should be preserved since I would like full fidelity when creating the configuration types for each camera implementation, even adding subobjects if necessary.
对于这台特定的摄像机,我将配置IP地址和端口,对于其他一些摄像机,我将需要授权数据,对于其他一些摄像机,我将配置完全不同的内容.
For this particular camera I would configure an IP address and a port, for some other camera I would require authorization data, and for some other camera something completely different.
我希望拥有此配置的属性仅以字符串形式直接获取Json.
I would like for the property that would hold this configuration to just get the Json directly, still as a string.
这可能吗?
这是一个 LINQPad 示例,其中有一些注释掉了:
Here is a LINQPad example that has some bits commented out:
void Main()
{
const string configurationFile = @"[
{
""type"": ""UserQuery+Camera1"",
""configuration"": { ""id"": 10 }
},
{
""type"": ""UserQuery+Camera2"",
""configuration"": { ""name"": ""The second camera"" }
}
]";
var cameras = JsonConvert.DeserializeObject<Camera[]>(configurationFile);
foreach (var camera in cameras)
{
var type = Type.GetType(camera.Type);
var instance = Activator.CreateInstance(type, new object[0]) as ICamera;
// instance.Configure(camera.Configuration);
}
}
public class Camera
{
public string Type { get; set; }
public JObject Configuration { get; set; }
}
public interface ICamera
{
void Configure(string json);
}
public class Camera1 : ICamera
{
private class Configuration
{
public int Id { get; set; }
}
public void Configure(string json)
{
JsonConvert.DeserializeObject<Configuration>(json).Dump();
}
}
public class Camera2 : ICamera
{
private class Configuration
{
public string Name { get; set; }
}
public void Configure(string json)
{
JsonConvert.DeserializeObject<Configuration>(json).Dump();
}
}
两个要注释掉的位,即Camera
类中的属性和对Configure
方法的调用,正是我想要的.
The two commented out bits, namely the property in the Camera
class, and the call to the Configure
method, is what I'd like working.
是否有可以为该属性添加标签的东西,或者可以为该属性选择的其他类型的标签,可以使这项工作正常进行?
Is there something I can tag that property with, or some other type I can pick for that property, that would make this work?
我知道我可以使该属性成为动态属性,从而将JObject
填充到其中,但是每个相机实现的每个Configure
方法都必须处理JObject
而不是已知的非动态类型
I know I can make the property dynamic, which would stuff a JObject
into it, but then each Configure
method of each camera implementation would have to deal with a JObject
and not a known non-dynamic type.
推荐答案
如果您使用类型为JObject
的属性,它将解析但保留JSON:
It looks like if you use a property of type JObject
, that parses but preserves the JSON:
using System;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class Foo
{
public string Name { get; set; }
public int Age { get; set; }
public JObject Configuration { get; set; }
}
public class Test
{
public static void Main()
{
var json = File.ReadAllText("test.json");
var foo = JsonConvert.DeserializeObject<Foo>(json);
Console.WriteLine(foo.Configuration);
}
}
Test.json:
Test.json:
{
"name": "Jon",
"age": 10,
"configuration": {
"ip": "127.0.0.1",
"port": 8080
}
}
输出:
{
"ip": "127.0.0.1",
"port": 8080
}
我怀疑您可以直接从JObject
反序列化,但是如果您确实愿意,可以始终将其转换回string
.
I suspect you can deserialize straight from the JObject
, but you can always convert it back to a string
if you really want to.
这篇关于使用Json.Net反序列化,将子对象反序列化为包含json的字符串/类似字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!