Json.NET JsonConvert.DeserializeObject()返回空值
本文关键字:返回 空值 DeserializeObject NET JsonConvert Json | 更新日期: 2023-09-27 18:08:54
我试图反序列化这个字符串:
string _jsonObject = {'"Ad'":{'"Type'":'"Request"',
'"IdAd'":'"xxx@xxx.com'",
'"Category'":'"cat'",
'"SubCategory'":'"subcat'"},
'"Position'":{'"Latitude'":'"38.255'",
'"Longitude'":'"1.2'",
'"Imei'":'"0123456789'"};
}";
Message _message = JsonConvert.DeserializeObject<Message>(_jsonObject);
适用于"Ad",但不能实例化"Position"。知道吗?
我忘记把属性设为公共了。别忘了……
为了帮助那些可能遇到这个问题的人,或者与之相关的人……
在我的例子中,我有一个对象和其他对象的数组,这些子对象上的一个引用类型属性在反序列化后总是为空。我尝试了各种方法,包括下载JSON。Net源代码并逐步通过它来找到故障点。
长话短说,这个问题当然是我自己的。以下是我的JSON和类的高度简化版本。 JSON{
"$id": "1",
"RowCount": 10,
"Rows": [{
"$id": 2",
"ItemId": "1",
"ItemName": "Some Item",
"Owner": {
"Name": "John Doe",
"Id": "711D04F5-586F-4FD4-8369-4C00B51DD86F",
// other properties...
},
"OwnerId": "711D04F5-586F-4FD4-8369-4C00B51DD86F"
},
// more rows
]
}
public class Items
{
public int RowCount { get; set; }
public IEnumerable<Item> Rows { get; set; }
}
public class Item
{
private string ownerId;
public string ItemId { get; set; }
public string ItemName { get; set; }
public Person Owner { get; set; }
public string OwnerId
{
get { return this.ownerId; }
set {
if (value != this.ownerId)
{
this.Owner = null;
}
this.ownerId = value;
}
}
}
public class Person
{
public string Name { get; set; }
public string Id { get; set; }
// other properties
}
public class Items
{
public int RowCount { get; set; }
public IEnumerable<Item> Rows { get; set; }
}
public class Item
{
private string ownerId;
public string ItemId { get; set; }
public string ItemName { get; set; }
public Person Owner { get; set; }
public string OwnerId
{
get { return this.ownerId; }
set {
if (value != this.ownerId)
{
this.Owner = null;
}
this.ownerId = value;
}
}
}
public class Person
{
public string Name { get; set; }
public string Id { get; set; }
// other properties
}
实际情况是,由于Owner
属性在JSON中出现在OwnerId
属性之前,当设置OwnerId
属性时,setter代码确定当前值与要设置的值不相同(因为当前值为空),因此将Owner
属性设置为空。
为了修复它,我还检查了针对Owner
对象的id设置的值,如果它们相同,则跳过将Owner
设置为null。
无可否认,我的问题的原因可能对每个人都不一样,但这至少是一个警告,提醒你在反序列化期间初始化对象时仔细检查发生了什么。
我不知道你是如何试图反序列化的,但这应该工作....
string json = "{'"Ad'":{'"Type'":'"Request'", '"IdAd'":'"xxx@xxx.com'", '"Category'":'"cat'", '"SubCategory'":'"subcat'"},'"Position'":{'"Latitude'":'"38.255'", '"Longitude'":'"1.2'", '"Imei'":'"0123456789'"}}";
var obj = JsonConvert.DeserializeObject<RootObject>(json);
public class Ad
{
public string Type { get; set; }
public string IdAd { get; set; }
public string Category { get; set; }
public string SubCategory { get; set; }
}
public class Position
{
public string Latitude { get; set; }
public string Longitude { get; set; }
public string Imei { get; set; }
}
public class RootObject
{
public Ad Ad { get; set; }
public Position Position { get; set; }
}
在我的例子中,我的类属性有内部setter ,在将它们设置为public之后,问题就解决了。
在我的例子中有一个更微妙的错误。很容易在json键中错误地添加前导或尾随空格。当发生这种情况时,键无法识别,并且试图反序列化它时将值设置为null。
示例:{" id": 123}
由于前导空格 " id"
, id
字段无法被识别。要修复它,请将json改为"id"
。
确保JSON中的数组名称与类中的属性名称匹配
说明(寻找"组件"):
JSON:{
"Components": [
{
"Attribute1": "ABC",
"Attribute2": "XYZ"
}
]
}
类:public class MyClass
{
public IList<Component> Components { get; set; }
}
反序列化:
JsonConvert.DeserializeObject<MyClass>(File.ReadAllText(@"ComponentSet.json"))
我的问题是我在JSON字符串的开头包含了类名。我复制粘贴了另一个类的序列化输出,其中包含我想要反序列化的类,并且我有目的地包含了类名,认为这是正确的JSON字符串。一旦我从JSON字符串中删除了类名,它就可以很好地反序列化了。
本文有助于实现这一点:https://social.msdn.microsoft.com/Forums/windowsapps/en-US/4d766a28-ff38-477f-8abf-48ed01f74cd2/jsonconvertdeserializeobjectlttgtjsonstring-returning-all-propertieslttgt-as-null?forum=wpdevelop
我在这里没有看到这个答案,所以我把它包括进来,希望它能帮助那些犯了和我一样愚蠢错误的人。
我使用Newtonsoft从未遇到过任何问题。Json,但决定在最新的项目中使用内置的Json库。以null结果结束。结果显示以下操作将失败:
JSON:{
"myProperty": "abc"
}
类:public void MyClass
{
public string MyProperty { get; set; }
}
为什么会失败?"myProperty"in json是驼色大小写(以小写字母开头),而MyClass中的MyProperty以大写字母开头。如果你让这两种情况相同,它是有效的。我试着弄清楚如何为整个应用程序配置大小写不敏感,但显然这是不可能做到的,所以我回到了Newtonsoft。JSON,问题就解决了。
在我的例子中,这是因为我的类没有公共构造函数。
这是我的类最初的样子:
public class TreeGroup
{
public string Name { get; set; }
public SiteGroup Group { get; set; }
public List<TreeMimicObject> Children { get; set; }
public TreeGroup(SiteGroup item)
{
// Notice this constructor takes a SiteGroup object and there
// is no default constructor
}
}
所以我把上面的类改成了:
public class TreeGroup
{
public string Name { get; set; }
public SiteGroup Group { get; set; }
public List<TreeMimicObject> Children { get; set; }
public TreeGroup()
{
// Added this default constructor here!!
}
public TreeGroup(SiteGroup item)
{
// ...
}
}
成功了!
在我的情况下,问题是deserializeobject
返回null
时,试图将null
值从json转换为int
。
public class ItemCalcResModel
{
public int cartId;
}
我通过在项目中启用nullable
解决了这个问题:
#nullable enable
public class ItemCalcResModel
{
public int? cartId;
}
在我的情况下,这是因为我忘记了用JsonPropertyName属性装饰Location属性。修改:
public LatLongLocation Location {get; set; }
:
[JsonPropertyName("location")]
public LatLongLocation Location {get; set; }
在我的例子中,我天真地试图在构造函数中执行反序列化的额外逻辑。
当试图通过var deserializedItem = JsonConvert.DeserializeObject<MyClass>(item);
进行反序列化时,MyClass
的构造函数将显示所有值为空,即使反序列化之前的日志语句显示了一个有效的JSON字符串。
所以如果它对你或其他人有帮助,那可能是另一个需要检查的领域。在您的例子中,Message
类函数可能包含额外的逻辑。
。
public Message(string _thing1, string _thing2)
{
// setting values here
thing1 = _thing1;
byte[] data = Convert.FromBase64String(thing1);
// doing more stuff with data
thing2 = _thing2;
}