Определить, отсутствует ли в десериализованном объекте поле с классом 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, а затем проверять параметр с помощью поиска значения ключа, но кодовая база, в которой я работаю, использует приведенный выше шаблон, и я хотел бы сохранить его согласованным, если это возможно.
Ответы
Ответ 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
, иначе это будет действительное значение. Это позволяет вам иметь дополнительные настройки и оценивать их по умолчанию.