如何在 Json.Net 中的 JsonConvert DeserializeObject 之后获取所有不存在的键?
How to get all not exist keys after JsonConvert DeserializeObject in Json.Net?
您好,我正在使用 NewtonSoft Json.Net 反序列化我的 json 数据。我通常反序列化 json 字符串,但我想检查所有不存在的键。
例如这里有一个json数据。
{
"Hp": 100,
"PlayerInfo": {
"Atk": 10,
"Def": 20
},
"Mp": 100
}
我有一个可以匹配上面数据的结构。
[Serializable]
public struct CharaData
{
public int Hp;
[Serializable]
public struct PlayerInfoData
{
public int Atk;
public int Def;
public int Spd;
}
PlayerInfoData PlayerInfo;
}
我要像这样反序列化它。
JsonConvert.DeserializeObject<CharaData>(jsonStr);
json 数据中有一个 Mp
键,但在结构中没有。
并且在 PlayerInfoData
中 json 数据中没有 Spd
键,但在结构中有一个 Spd
字段。
- 嗯...Spd 字段似乎初始化为默认 0 值,这可能是一个错误。
所以我想检查哪些键不在结构中。
以及哪些结构字段因为不存在而没有被反序列化。
我会尽最大努力防止这些情况发生,但是如果在从 json 数据反序列化的过程中丢失了某些键,我会记录以查找为什么反序列化没有发生的问题
完全成功。
[Error][CharaData::Mp key not exist in json string]
[Error][CharaData::PlayerInfo::Spd field not exist in struct]
似乎没有任何方法可以在 JsonConvert class 中检查它。
我看到了
[JsonProperty(Required = Required.Always)]
但这不会检查所有键。
这是否需要编写自定义 json 转换器?
使用此代码
var result= JsonConvert.DeserializeObject<CharaData>(jsonStr);
var mp=result.Mp;
var playerInfo=result.PlayerInfo;
如果您想知道存在哪些密钥,只需检查它们是否为空。默认情况下,所有键都是空的。如果它们不为空,则意味着它们从 json 中获取了值。例如,您可以使用此代码
if (mp==null) Console.WriteLine ("mp is not exist in json");
另一种方法是使用反射来检查所有属性
var props = result.GetType().GetProperties();
var nulls = new List<string>();
foreach (var prop in props)
{
var propInstance = prop.GetValue(result, null);
if (propInstance == null) nulls.Add(prop.Name);
if (prop.Name == "PlayerInfo")
{
var prps = prop.PropertyType.GetProperties();
foreach (var prp in prps)
if (prp.GetValue(propInstance, null) == null) nulls.Add(prop.Name+"."+prp.Name);
}
}
foreach (var n in nulls)
Console.WriteLine(n + " doesn't have value");
测试结果
PlayerInfo.Spd doesn't have value
类
public class PlayerInfo
{
public int? Atk { get; set; }
public int? Def { get; set; }
public int? Spd { get; set; }
}
public class CharaData
{
public int? Hp { get; set; }
public PlayerInfo PlayerInfo { get; set; }
public int? Mp { get; set; }
}
你的问题是双重的:
- 找到缺失的字段
- 找到额外的字段
在深入研究细节之前,让我们将 CharaData
分成两个 classes
[Serializable]
public class CharaData
{
public int Hp;
public PlayerInfoData PlayerInfo;
}
[Serializable]
public class PlayerInfoData
{
public int Atk;
public int Def;
public int Spd;
}
缺少字段
此解决方案依赖于 JsonSchema
private static Lazy<JSchema> schema = new Lazy<JSchema>(() => {
var generator = new JSchemaGenerator();
return generator.Generate(typeof(CharaData));
}, true);
public static void ReportMissingFields(string json)
{
var semiParsed = JObject.Parse(json);
try
{
semiParsed.Validate(schema.Value);
}
catch (JSchemaValidationException ex)
{
Console.WriteLine(ex.ValidationError.Message);
}
}
schema
以惰性方式存储 CharaData
的 json 模式
Validate
将 json
与架构进行比较,如果不匹配,则抛出 JSchemaValidationException
- 它公开了一个 属性 类型是
ValidationError
其中包含很多关于不匹配的信息
额外字段
此解决方案依赖于JsonExtensionDataAttribute
[Serializable]
internal class CharaDataExtras: CharaData
{
[JsonExtensionData]
public IDictionary<string, JToken> ExtraFields;
}
...
public static void ReportExtraFields(string json)
{
var result = JsonConvert.DeserializeObject<CharaDataExtras>(json);
foreach (var field in result.ExtraFields)
{
Console.WriteLine($"An extra field has found, called {field.Key}");
}
}
- 我已将
CharaData
定义为 class 以便能够从中导出 << CharaDataExtras
- 每个额外的字段都将放入
ExtraFields
字典
用法
var json = File.ReadAllText("sample.json");
ReportMissingFields(json);
ReportExtraFields(json);
输出:
Required properties are missing from object: Spd.
An extra field has found, called Mp
您好,我正在使用 NewtonSoft Json.Net 反序列化我的 json 数据。我通常反序列化 json 字符串,但我想检查所有不存在的键。
例如这里有一个json数据。
{
"Hp": 100,
"PlayerInfo": {
"Atk": 10,
"Def": 20
},
"Mp": 100
}
我有一个可以匹配上面数据的结构。
[Serializable]
public struct CharaData
{
public int Hp;
[Serializable]
public struct PlayerInfoData
{
public int Atk;
public int Def;
public int Spd;
}
PlayerInfoData PlayerInfo;
}
我要像这样反序列化它。
JsonConvert.DeserializeObject<CharaData>(jsonStr);
json 数据中有一个
Mp
键,但在结构中没有。并且在
PlayerInfoData
中 json 数据中没有Spd
键,但在结构中有一个Spd
字段。- 嗯...Spd 字段似乎初始化为默认 0 值,这可能是一个错误。
所以我想检查哪些键不在结构中。 以及哪些结构字段因为不存在而没有被反序列化。
我会尽最大努力防止这些情况发生,但是如果在从 json 数据反序列化的过程中丢失了某些键,我会记录以查找为什么反序列化没有发生的问题 完全成功。
[Error][CharaData::Mp key not exist in json string]
[Error][CharaData::PlayerInfo::Spd field not exist in struct]
似乎没有任何方法可以在 JsonConvert class 中检查它。 我看到了
[JsonProperty(Required = Required.Always)]
但这不会检查所有键。 这是否需要编写自定义 json 转换器?
使用此代码
var result= JsonConvert.DeserializeObject<CharaData>(jsonStr);
var mp=result.Mp;
var playerInfo=result.PlayerInfo;
如果您想知道存在哪些密钥,只需检查它们是否为空。默认情况下,所有键都是空的。如果它们不为空,则意味着它们从 json 中获取了值。例如,您可以使用此代码
if (mp==null) Console.WriteLine ("mp is not exist in json");
另一种方法是使用反射来检查所有属性
var props = result.GetType().GetProperties();
var nulls = new List<string>();
foreach (var prop in props)
{
var propInstance = prop.GetValue(result, null);
if (propInstance == null) nulls.Add(prop.Name);
if (prop.Name == "PlayerInfo")
{
var prps = prop.PropertyType.GetProperties();
foreach (var prp in prps)
if (prp.GetValue(propInstance, null) == null) nulls.Add(prop.Name+"."+prp.Name);
}
}
foreach (var n in nulls)
Console.WriteLine(n + " doesn't have value");
测试结果
PlayerInfo.Spd doesn't have value
类
public class PlayerInfo
{
public int? Atk { get; set; }
public int? Def { get; set; }
public int? Spd { get; set; }
}
public class CharaData
{
public int? Hp { get; set; }
public PlayerInfo PlayerInfo { get; set; }
public int? Mp { get; set; }
}
你的问题是双重的:
- 找到缺失的字段
- 找到额外的字段
在深入研究细节之前,让我们将 CharaData
分成两个 classes
[Serializable]
public class CharaData
{
public int Hp;
public PlayerInfoData PlayerInfo;
}
[Serializable]
public class PlayerInfoData
{
public int Atk;
public int Def;
public int Spd;
}
缺少字段
此解决方案依赖于 JsonSchema
private static Lazy<JSchema> schema = new Lazy<JSchema>(() => {
var generator = new JSchemaGenerator();
return generator.Generate(typeof(CharaData));
}, true);
public static void ReportMissingFields(string json)
{
var semiParsed = JObject.Parse(json);
try
{
semiParsed.Validate(schema.Value);
}
catch (JSchemaValidationException ex)
{
Console.WriteLine(ex.ValidationError.Message);
}
}
schema
以惰性方式存储CharaData
的 json 模式Validate
将json
与架构进行比较,如果不匹配,则抛出JSchemaValidationException
- 它公开了一个 属性 类型是
ValidationError
其中包含很多关于不匹配的信息
- 它公开了一个 属性 类型是
额外字段
此解决方案依赖于JsonExtensionDataAttribute
[Serializable]
internal class CharaDataExtras: CharaData
{
[JsonExtensionData]
public IDictionary<string, JToken> ExtraFields;
}
...
public static void ReportExtraFields(string json)
{
var result = JsonConvert.DeserializeObject<CharaDataExtras>(json);
foreach (var field in result.ExtraFields)
{
Console.WriteLine($"An extra field has found, called {field.Key}");
}
}
- 我已将
CharaData
定义为 class 以便能够从中导出 <<CharaDataExtras
- 每个额外的字段都将放入
ExtraFields
字典
用法
var json = File.ReadAllText("sample.json");
ReportMissingFields(json);
ReportExtraFields(json);
输出:
Required properties are missing from object: Spd.
An extra field has found, called Mp