Json.NET, Невозможно дезацинировать тип с нулевым значением
Я пытаюсь преобразовать JSON в объект С# с помощью Json.NET. Объект выглядит так на С#:
public class MyObject
{
public int? integerValue {get;set;}
public DateTime? dateTimeValue {get;set;}
}
Но когда я запускаю JsonConvert.DeserializeObject()
на входящем JSON, я получаю следующее исключение:
Невозможно найти конструктор для использования для типа System.Nullable`1 [System.Int32]. класс должен либо иметь значение по умолчанию конструктор или только один конструктор с аргументами.
--- EDIT ----
Ну, получается, что после многих тестов проблема сводится к тому, что мой ввод для моего JSON был таким:
{integerValue:{}, dateTimeValue: {} }
вместо:
{integerValue: null, dateTimeValue: null}
Оказывается, что {} является допустимым способом представления нулевого объекта в JSON, но парсер JSON.Net не знал, чтобы лечить {} токены так же, как "null" при де-сериализации.
Спасибо всем за ваш вклад!
Ответы
Ответ 1
Ошибка говорит вам, что он не может найти конструктор, который он может использовать для десериализации.
Попробуйте добавить к классу конструктор по умолчанию:
public class MyObject
{
public int? integerValue { get; set; }
public DateTime? dateTimeValue { get; set; }
public MyObject(){}
}
Патрик.
- EDIT -
Итак, я только что создал простое консольное приложение, использующее MyObject, с конструктором по умолчанию и без него, и я не получаю никаких ошибок. Вот мой пример:
class Program
{
static void Main(string[] args)
{
var mo = new MyObject { integerValue = null, dateTimeValue = null };
var ser = Newtonsoft.Json.JsonConvert.SerializeObject(mo);
var deser = Newtonsoft.Json.JsonConvert.DeserializeObject(ser, typeof(MyObject));
}
}
public class MyObject
{
public int? integerValue { get; set; }
public DateTime? dateTimeValue { get; set; }
}
У меня нет исключений...
Вы можете показать пример JSON, который вы пытаетесь десериализовать?
Ответ 2
Решением для меня было создание Конвертера в соответствии с этим ответом
public class BoolConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(((bool)value) ? 1 : 0);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value == null || reader.Value.ToString() == "False")
{
return false;
}
return true;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(bool);
}
}
И чем указывается в модели
[JsonConverter(typeof(BoolConverter))]
public Boolean bold;
Ответ 3
Я не знаю, это правильный ответ или нет, но по крайней мере вы можете создать собственный конвертер для Nullable < > , он очень помогает мне с сериализацией/десериализацией DataRow, а также не имеет конструктора по умолчанию. Вот образец
Ответ 4
Готовая версия ответа @Patrick:
static void Main(string[] args)
{
var mo = new MyObject ();
var ser = Newtonsoft.Json.JsonConvert.SerializeObject(mo);
var myStr = "{}";
var myStr1 = "{tITi: 10}";
var myStr2 = "{integerValue: 10}";
var deser0 = Newtonsoft.Json.JsonConvert.DeserializeObject(ser, typeof(MyObject));
var deser1 = Newtonsoft.Json.JsonConvert.DeserializeObject(myStr, typeof(MyObject));
var deser2 = Newtonsoft.Json.JsonConvert.DeserializeObject(myStr1, typeof(MyObject));
var deser3 = Newtonsoft.Json.JsonConvert.DeserializeObject(myStr2, typeof(MyObject));
}
public class MyObject
{
public int? integerValue { get; set; }
public DateTime? dateTimeValue { get; set; }
public int toto { get; set; } = 5;
public int Titi;
}
Вывод:
?deser0
{ConsoleApplication1.MyObject}
Titi: 0
dateTimeValue: null
integerValue: null
toto: 5
?deser1
{ConsoleApplication1.MyObject}
Titi: 0
dateTimeValue: null
integerValue: null
toto: 5
?deser2
{ConsoleApplication1.MyObject}
Titi: 10
dateTimeValue: null
integerValue: null
toto: 5
?deser3
{ConsoleApplication1.MyObject}
Titi: 0
dateTimeValue: null
integerValue: 10
toto: 5