为什么 JObject 不转换 JSON 字符串?
Why isn't JObject converting the JSON string?
我不知道我这样做是否正确,但我有以下 class 来尝试验证和解析 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);
}
}
大多数时候架构检查工作正常,但有时我需要像这样反序列化字符串:
"\"User sent null or empty data\""
在这种情况下,模式验证应该 return 为假。但是,当我调用 JObject.Parse
时出现错误:
Newtonsoft.Json.JsonReaderException: 'Error reading JObject from JsonReader. Current JsonReader item is not an object: String. Path '',
我正在使用上面显示的架构。
如果我没理解错,我不能解析成字符串?但是在这种情况下我该怎么办?如果无法解析 JSON,我该如何验证它是否正确?
(符合此架构的JSON 正确解析。)
您遇到错误,因为 "\"User sent null or empty data\""
不是 JSON 对象,因此 JObject.Parse
无法解析它。相反,您应该使用 JToken.Parse
. This method can handle any kind of JSON -- objects, arrays and simple values. The 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);
}
}
我不知道我这样做是否正确,但我有以下 class 来尝试验证和解析 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);
}
}
大多数时候架构检查工作正常,但有时我需要像这样反序列化字符串:
"\"User sent null or empty data\""
在这种情况下,模式验证应该 return 为假。但是,当我调用 JObject.Parse
时出现错误:
Newtonsoft.Json.JsonReaderException: 'Error reading JObject from JsonReader. Current JsonReader item is not an object: String. Path '',
我正在使用上面显示的架构。
如果我没理解错,我不能解析成字符串?但是在这种情况下我该怎么办?如果无法解析 JSON,我该如何验证它是否正确?
(符合此架构的JSON 正确解析。)
您遇到错误,因为 "\"User sent null or empty data\""
不是 JSON 对象,因此 JObject.Parse
无法解析它。相反,您应该使用 JToken.Parse
. This method can handle any kind of JSON -- objects, arrays and simple values. The 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);
}
}