Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json.NET, Unable to de-serialize nullable type

Tags:

json

c#

json.net

I'm trying to convert JSON to C# object using Json.NET. The object looks like this in C#:

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

But when I run JsonConvert.DeserializeObject() on the incoming JSON, I get the following Exception:

Unable to find a constructor to use for type System.Nullable`1[System.Int32]. A class should either have a default constructor or only one constructor with arguments.

--- EDIT ----

Well it turns out that after doing many tests, the problem boils down to that my input for my JSON was like this:

{integerValue:{}, dateTimeValue: {} }

instead of:

{integerValue: null, dateTimeValue: null}

It turns out that the {} is a valid way of representing a null object in JSON but the JSON.Net parser did not know to treat {} tokens the same way as 'null' when de-serializing.

Thanks everyone for your input!

like image 913
7wp Avatar asked Jan 28 '10 19:01

7wp


3 Answers

The error is telling you that it cant find a a constructor that it can use for the deserialization.

Try adding a default constructor to the class:

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

    public MyObject(){}
} 

Patrick.

--EDIT--

So I've just created a simple console app using your MyObject, with and without a default constructor and I'm getting no errors. Here is my example:

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; }        
}  

I get no exceptions...

Can you show an example of the JSON that you are trying to deserialize?

like image 91
Patrick Avatar answered Nov 08 '22 17:11

Patrick


The solution for me was to create Converter according to this answer

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);
    }
}

And than specify in model

[JsonConverter(typeof(BoolConverter))]
public Boolean bold;
like image 32
Kateryna Gridina Avatar answered Nov 08 '22 19:11

Kateryna Gridina


I dont know is it right answer or not, but at least You can create custom converter for Nullable<>, it helps me a lot with DataRow serializing/deserializing it also does not have default constructor. Here is sample

like image 42
Sergey Mirvoda Avatar answered Nov 08 '22 17:11

Sergey Mirvoda