Почему JObject не преобразует строку JSON? - PullRequest
1 голос
/ 19 сентября 2019

Я не знаю, правильно ли я это сделал или нет, но у меня есть следующий класс для проверки и анализа 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: «Ошибка чтения JObject из JsonReader.Текущий элемент JsonReader не является объектом: String.Path '',

Я использую схему, которую я показал выше.

Если я правильно понимаю, я не могу разобрать строку?Но тогда что мне делать в этом случае?Как проверить правильность JSON, если я не могу его проанализировать?

(JSON, который соответствует этой схеме, правильно анализирует.)

1 Ответ

1 голос
/ 20 сентября 2019

Вы получаете сообщение об ошибке, поскольку "\"User sent null or empty data\"" не является объектом JSON, поэтому он не может быть проанализирован JObject.Parse.Вместо этого вы должны использовать JToken.Parse.Этот метод может обрабатывать любой тип JSON - объекты, массивы и простые значения.Метод расширения IsValid определен для работы на JToken, поэтому он все равно должен нормально работать с этим изменением.

Кроме того, когда проверка JToken прошла успешно, выне нужно десериализовать JSON во второй раз с JsonConvert.DeserializeObject<T>().Вы можете преобразовать токен в свой объект напрямую, используя 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);
    }
}
...