【问题标题】:Why isn't JObject converting the JSON string?为什么 JObject 不转换 JSON 字符串?
【发布时间】:2019-09-19 09:49:20
【问题描述】:

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

【问题讨论】:

  • 您尝试针对架构解析/验证的 JSON 字符串是什么?
  • 我写了这一行:--我检查架构工作正常,但有时我需要反序列化字符串,如 "\"User sent null or empty data\""
  • 好的,我现在知道发生了什么。我已经添加了答案。

标签: c# json parsing jsonschema


【解决方案1】:

您收到错误,因为"\"User sent null or empty data\"" 不是 JSON 对象,因此JObject.Parse 无法解析它。相反,您应该使用JToken.Parse。此方法可以处理任何类型的 JSON——对象、数组和简单值。 IsValid 扩展方法被定义为在 JToken 上工作,所以它应该仍然可以正常工作。

顺便说一句,当JToken 验证成功时,您不需要使用JsonConvert.DeserializeObject&lt;T&gt;() 再次反序列化 JSON。您可以直接使用JToken.ToObject&lt;T&gt;() 将令牌转换为您的对象。

也就是说,改变这段代码:

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

【讨论】:

  • 没有任何问题(返回默认),谢谢您的回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-24
  • 1970-01-01
  • 2016-03-11
  • 2017-11-09
  • 1970-01-01
  • 2018-10-26
相关资源
最近更新 更多