我不知道我是否正确地做到了这一点,但是我有下面的类尝试验证和解析JSON:
public static class JsonHelper
{
internal const string UserResetDataScheme = @"{
'title' : 'UserResetDataModel',
'type' : 'object',
'properties': {
'Role' : {'type' : 'integer'},
'Email' : {'type' : 'string'},
},
required: [ 'Role', 'Email']
}";
internal static T TryParseJson<T>(this string json, string schema) where T : new()
{
var parsedSchema = JSchema.Parse(schema);
var jObject = JObject.Parse(json);
return jObject.IsValid(parsedSchema) ? JsonConvert.DeserializeObject<T>(json) : default(T);
}
}
大多数时候,架构检查都可以正常工作,但是有时我需要反序列化这样的字符串:
“ \”用户发送的数据为空或空数据\“”
在这种情况下,架构验证应返回false。但是,当我致电JObject.Parse
时出现错误:
Newtonsoft.Json.JsonReaderException:'从JsonReader读取JObject时出错。当前JsonReader项不是对象:字符串。路径'',
我正在使用上面显示的模式。
如果我理解此权利,就无法解析为字符串?但是在这种情况下我该怎么办?如果无法解析,如何验证JSON不正确?
(符合此架构的JSON正确解析。)
答案 0 :(得分:1)
由于"\"User sent null or empty data\""
不是JSON对象,因此无法得到JObject.Parse
的解析,您会收到错误消息。相反,您应该使用JToken.Parse
。此方法可以处理任何类型的JSON(对象,数组和简单值)。 IsValid
扩展方法被定义为可在JToken
上使用,因此,此更改仍然可以正常使用。
顺便说一句,当JToken
成功验证时,您无需再次使用JsonConvert.DeserializeObject<T>()
反序列化JSON。您可以直接使用JToken.ToObject<T>()
将令牌转换为对象。
换句话说,更改此代码:
var jObject = JObject.Parse(json);
return jObject.IsValid(parsedSchema) ? JsonConvert.DeserializeObject<T>(json) : default(T);
对此:
var jToken = JToken.Parse(json);
return jToken.IsValid(parsedSchema) ? jToken.ToObject<T>() : default(T);
为了更加安全,您可以在解析周围放置try / catch块。这样,如果您得到的字符串根本不是JSON,则也可以处理。因此,您将拥有:
internal static T TryParseJson<T>(this string json, string schema) where T : new()
{
var parsedSchema = JSchema.Parse(schema);
try
{
var jToken = JToken.Parse(json);
return jToken.IsValid(parsedSchema) ? jToken.ToObject<T>() : default(T);
}
catch (JsonException ex)
{
// optionally log the exception here
return default(T);
}
}