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
Json.NET, Unable to de-serialize nullable type
提问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
回答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