C# Json.NET,无法反序列化可为空类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2157156/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:01:09  来源:igfitidea点击:

Json.NET, Unable to de-serialize nullable type

c#jsonjson.net

提问by 7wp

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

我正在尝试使用 Json.NET 将 JSON 转换为 C# 对象。该对象在 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:

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

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.

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

--- EDIT ----

- - 编辑 - -

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

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

{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.

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

Thanks everyone for your input!

谢谢各位的意见!

采纳答案by Patrick

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:

所以我刚刚使用你的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; }        
}  

I get no exceptions...

我没有例外...

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

你能展示一个你试图反序列化的 JSON 的例子吗?

回答by Sergey Mirvoda

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

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

回答by Kateryna Gridina

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;

回答by Serge

A completed version of the @Patrick answer:

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

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