c# - 如何将 json 反序列化为结构?
问题描述
我有一个这样的类映射:
public class Settings
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("content")]
public ContentStructure Content { get; set; }
}
public struct ContentStructure
{
public Content ContentClass;
public string ContentString;
public static implicit operator ContentStructure(Content content) => new ContentStructure { ContentClass = content };
public static implicit operator ContentStructure(string @string) => new ContentStructure { ContentString = @string };
}
public class Content
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("duration")]
public long Duration { get; set; }
}
当我尝试反序列化以下 JSON 字符串时:
{
"id": "any_id",
"type": "any_type",
"content": {
"id": "any_id",
"duration": 1000
}
}
我总是使用属性 settings.Content 获取反序列化的设置对象。ContentClass null,但只要我的 JSON 字符串具有"content"
字符串(而不是对象)的属性,结构字段ContentString
就会正确出现。我做错了什么?如何正确转换上面的 JSON 字符串?
解决方案
另一种解决方案可能是利用JsonSchema
首先让我们重新定义您的数据模型:
public abstract class Settings
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
}
public class SettingsV1 : Settings
{
[JsonProperty("content")]
public string Content { get; set; }
}
public class SettingsV2 : Settings
{
[JsonProperty("content")]
public Content Content { get; set; }
}
public class Content
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("duration")]
public long Duration { get; set; }
}
- 而不是有一个中间人(
ContentStructure
)而不是你可以有两个单独的Settings
版本 - 公共字段在抽象基类中定义
现在,您可以使用这两个版本化的类来定义 json 模式:
private static JSchema schemaV1;
private static JSchema schemaV2;
//...
var generator = new JSchemaGenerator();
schemaV1 = generator.Generate(typeof(SettingsV1));
schemaV2 = generator.Generate(typeof(SettingsV2));
最后,您需要做的就是在DeserializeObject
使用正确的类型调用之前进行初步检查:
Settings settings = null;
var semiParsed = JObject.Parse(json);
if (semiParsed.IsValid(schemaV1))
{
settings = JsonConvert.DeserializeObject<SettingsV1>(json);
}
else if (semiParsed.IsValid(schemaV2))
{
settings = JsonConvert.DeserializeObject<SettingsV2>(json);
}
else
{
throw new NotSupportedException("The provided json format is not supported");
}
推荐阅读
- javascript - 在赛普拉斯测试中尝试使用 Auth0 登录时出错
- python - 如何控制子采样以使 xgb.cv 和 cross_validate 产生相同的结果?
- qt - 如何设置计时器以更改 Qt 标签中的图片
- python - 这个ROC曲线的图看起来很奇怪人脸识别sklearn
- python - 如何在分类类型上设置索引?
- memgraphdb - Memgraph 数据库问题:复制、分区、并行化、图存储
- c# - c# Selenium,选择特定的 Firefox Profile
- javascript - javascript - 方法调用中的 var 未重新定义
- php - 使用其索引将字符串中的第一个字符替换为多个字符
- ansible - 通过 sudo Ansible-Playbook