Json.NET,无法对可空类型进行反序列化

时间:2010-01-28 19:06:11

标签: c# json json.net

我正在尝试使用Json.NET将JSON转换为C#对象。对象在C#中看起来像这样:

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

但是当我在传入的JSON上运行JsonConvert.DeserializeObject()时,我得到以下异常:

  

无法找到要使用的构造函数   对于类型   System.Nullable`1 [System.Int32]。一个   class应该有一个默认值   构造函数或只有一个构造函数   带参数。

---编辑----

事实证明,经过多次测试后,问题归结为我对JSON的输入是这样的:

{integerValue:{}, dateTimeValue: {} }

而不是:

{integerValue: null, dateTimeValue: null}

事实证明,{}是一种在JSON中表示空对象的有效方式,但是JSON.Net解析器在反序列化时不知道以与'null'相同的方式处理{}令牌。

感谢大家的意见!

5 个答案:

答案 0 :(得分:15)

该错误告诉您它无法找到可用于反序列化的构造函数。

尝试在类中添加默认构造函数:

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

        public MyObject(){}
    } 

帕特里克。

- 编辑 -

所以我刚刚使用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示例?

答案 1 :(得分:10)

我的解决方案是根据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);
    }
}

然后在模型中指定

[JsonConverter(typeof(BoolConverter))]
public Boolean bold;

答案 2 :(得分:3)

我不知道它是否正确答案,但至少你可以为Nullable<>创建自定义转换器,它帮助我很多DataRow序列化/反序列化它也没有默认构造函数。这是sample

答案 3 :(得分:0)

@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

答案 4 :(得分:0)

还要确保您的属性具有公共设置器,以便反序列化工作。