24

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!

4
  • Can you add the JSON you're trying to deserialize? Commented Jan 28, 2010 at 21:14
  • I had the same problem, except {value:"null"} instead of {value:null}. Commented Mar 25, 2013 at 16:25
  • I just want to add this link to a related question that helped me solved this same problem: stackoverflow.com/questions/6507889/… Add: [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] Commented Nov 3, 2016 at 5:51
  • have same issue with Newtonsoft.Json 6.0.0 rv v4.0.30319 Commented Sep 15, 2017 at 11:18

5 Answers 5

19

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?

Sign up to request clarification or add additional context in comments.

5 Comments

Patrick, I do not think it is as simple as that. The error is not that there is no default constructor for MyObject. The error is saying that there is no default constructor for type System.Nullable ! Every class that is user defined gets an implicit default parameter-less constructor by the compiler. Unless the constructor is marked private.
You're right, the parameter-less constructor is added by the compiler - But I've had many instances in that past when developing WCF REST services (XML and JSON) where I would get serialization isses if I didn't specifically add a parameterless constructor. So in theory, what you say should work but in practice, I've had a different experience. I'll try to set up a project using the same tools you have to see if I can come up with a better option.
Thanks for your efforts. I just found out what the problem was. Turns out my JSON input sring had {} instead of null for the null values. Although {} is still valid in JSON, the JSON.Net converter did not understand to handle {} the same way as null.
I'll accept your answer as accepted since it is the one that triggered me to find the solution.
Just to help someone who might have overlooked the the access modifier of the property - if you specify this: public DateTime? dateTimeValue { get; private set; } you will end up not having the date time set due to protection level. Man, I felt stupid after starring at my own code for hours when I discovered this...
11

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;

Comments

3

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

1 Comment

Sergey. Thanks for helping. But it turns out the problem was something different. See my edits in my posted question.
0

A completed version of the @Patrick answer:

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

Output:

?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

Comments

0

Also make sure your properties have public setters in order for deserialization to work.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.