为什么JObject不转换JSON字符串?

时间:2019-09-19 09:49:20

标签: c# json parsing jsonschema

我不知道我是否正确地做到了这一点,但是我有下面的类尝试验证和解析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正确解析。)

1 个答案:

答案 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);
    }
}