Подтвердить что ты не робот

Определить, отсутствует ли в десериализованном объекте поле с классом JsonConvert в Json.NET

Я пытаюсь десериализовать некоторые объекты JSON с помощью Json.NET. Однако я обнаружил, что при десериализации объекта, который не имеет свойств, которые я ищу, не возникает никакой ошибки, но при доступе к свойствам возвращается значение по умолчанию для свойств. Важно, чтобы я мог определить, когда я десериализировал неправильный тип объекта. Пример кода:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Json_Fail_Test
{
    class Program
    {
        [JsonObject(MemberSerialization.OptOut)]
        private class MyJsonObjView
        {
            [JsonProperty("MyJsonInt")]
            public int MyJsonInt { get; set; }
        }

        const string correctData = @"
        {
            'MyJsonInt': 42
        }";

        const string wrongData = @"
        {
            'SomeOtherProperty': 'fbe8c20b'
        }";

        static void Main(string[] args)
        {
            var goodObj = JsonConvert.DeserializeObject<MyJsonObjView>(correctData);
            System.Console.Out.WriteLine(goodObj.MyJsonInt.ToString());

            var badObj = JsonConvert.DeserializeObject<MyJsonObjView>(wrongData);
            System.Console.Out.WriteLine(badObj.MyJsonInt.ToString());
        }
    }
}

Выход этой программы: 42 0

Я бы предпочел, чтобы исключение молча провалилось. Если не считать, есть ли способ определить, не удалось ли при сериализации найти параметр?

Я знаю, что могу анализировать данные с помощью объекта Json, а затем проверять параметр с помощью поиска значения ключа, но кодовая база, в которой я работаю, использует приведенный выше шаблон, и я хотел бы сохранить его согласованным, если это возможно.

4b9b3361

Ответ 1

Сериализатор Json.Net имеет параметр MissingMemberHandling, который вы можете установить на Error. (По умолчанию это Ignore.) Это приведет к тому, что сериализатор будет генерировать JsonSerializationException во время десериализации всякий раз, когда он встречает свойство JSON, для которого нет соответствующего свойства в целевом классе.

static void Main(string[] args)
{
    try
    {
        JsonSerializerSettings settings = new JsonSerializerSettings();
        settings.MissingMemberHandling = MissingMemberHandling.Error;

        var goodObj = JsonConvert.DeserializeObject<MyJsonObjView>(correctData, settings);
        System.Console.Out.WriteLine(goodObj.MyJsonInt.ToString());

        var badObj = JsonConvert.DeserializeObject<MyJsonObjView>(wrongData, settings);
        System.Console.Out.WriteLine(badObj.MyJsonInt.ToString());
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.GetType().Name + ": " + ex.Message);
    }
}

Результат:

42
JsonSerializationException: Could not find member 'SomeOtherProperty' on object
of type 'MyJsonObjView'. Path 'SomeOtherProperty', line 3, position 33.

Ответ 2

Просто добавьте [JsonProperty(Required = Required.Always)] к требуемым свойствам, и он будет генерировать исключение, если свойство не существует при десериализации.

[JsonProperty(Required = Required.Always)]
 public int MyJsonInt { get; set; }

Ответ 3

Поместите следующие атрибуты на требуемые свойства:

[DataMember(IsRequired = true)]

Если элемент отсутствует, он выкинет исключение Newtonsoft.Json.JsonSerializationException.

Как предложил Брайан ниже, вам также понадобится этот атрибут в вашем классе:

[DataContract]

Ответ 4

Просто определите своих членов в вашем классе определения с вопросительным знаком "?" int?:

private class MyJsonObjView
{
    [JsonProperty("MyJsonInt")]
    public int? MyJsonInt { get; set; }
}

Если он не инициализирован, он будет равен null, иначе это будет действительное значение. Это позволяет вам иметь дополнительные настройки и оценивать их по умолчанию.