Json.NET, Невозможно десериализовать обнуляемый тип - PullRequest
20 голосов
/ 28 января 2010

Я пытаюсь преобразовать JSON в объект C # с помощью Json.NET. Объект выглядит следующим образом в C #:

public class MyObject 
{
   public int? integerValue {get;set;}
   public DateTime? dateTimeValue {get;set;}
}

Но когда я запускаю JsonConvert.DeserializeObject() на входящем JSON, я получаю следующее исключение:

Невозможно найти конструктор для использования для типа System.Nullable`1 [System.Int32]. класс должен иметь значение по умолчанию конструктор или только один конструктор с аргументами.

--- РЕДАКТИРОВАТЬ ----

Что ж, получается, что после многих тестов проблема сводится к тому, что мой ввод для моего JSON был таким:

{integerValue:{}, dateTimeValue: {} }

вместо:

{integerValue: null, dateTimeValue: null}

Оказывается, что {} является допустимым способом представления нулевого объекта в JSON, но синтаксический анализатор JSON.Net не знал, что при десериализации сериализации токены {} должны обрабатываться так же, как и 'нулевые'.

Спасибо всем за ваш вклад!

Ответы [ 4 ]

15 голосов
/ 28 января 2010

Ошибка говорит вам, что он не может найти конструктор, который он может использовать для десериализации.

Попробуйте добавить конструктор по умолчанию в класс:

public class MyObject
    {
        public int? integerValue { get; set; }
        public DateTime? dateTimeValue { get; set; }

        public MyObject(){}
    } 

Patrick.

- 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, который вы пытаетесь десериализовать?

10 голосов
/ 23 января 2015

Решением для меня было создать конвертер по этому ответу

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 голосов
/ 28 января 2010

Я не знаю, правильный это ответ или нет, но, по крайней мере, вы можете создать собственный конвертер для Nullable <>, он мне очень помогает с сериализацией / десериализацией DataRow, у него также нет конструктора по умолчанию. Вот образец

0 голосов
/ 22 декабря 2016

Завершенная версия ответа @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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...