你好,我正在使用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);
Mp
键,但在结构上没有。PlayerInfoData
中,json数据中没有Spd
键,但是在结构中有一个Spd
字段。- _Well... Spd field seems initialize as a default 0 value and it could potentially be a bug._
所以我想检查哪些键不在结构中。以及哪些结构字段由于不存在而没有反序列化。
我将尽力防止这种情况发生,但是如果在从json数据反序列化的过程中缺少了一些键,我将记录下来,以找到反序列化为什么没有完全成功的问题。
[Error][CharaData::Mp key not exist in json string]
[Error][CharaData::PlayerInfo::Spd field not exist in struct]
在JsonConvert类中似乎没有任何方法来检查它。我看到了
[JsonProperty(Required = Required.Always)]
但这并不能检查所有的钥匙。这需要编写自定义json转换器吗?
发布于 2021-11-19 08:56:51
你的问题有两个:
在深入研究细节之前,让我们将CharaData
分为两个类
[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
定义为类,以便能够从中派生<< 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
发布于 2021-11-18 17:14:53
使用此代码
var result= JsonConvert.DeserializeObject<CharaData>(jsonStr);
var mp=result.Mp;
var playerInfo=result.PlayerInfo;
如果您想知道存在什么键,只需检查它们是否为null。默认情况下,所有键都为空。如果它们不是null,就意味着它们从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; }
}
https://stackoverflow.com/questions/70023956
复制相似问题