Json.NET 的 JsonConvert.DeserializeObject() 方法返回 null 值。

15

我尝试对这个字符串进行反序列化

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"。有什么想法吗?


3
序列化还是反序列化?你的声明在哪里?代码呢? - L.B
2
https://en.wiktionary.org/wiki/instanciate - Mark
13个回答

49

我忘记把属性设为public了。别忘了这样做...


15
{ get; private set; } 是我的问题!! (注:原句为英文编程术语,意思是get方法可读取该属性值,但set方法仅在类内部可用于设置该属性的值。) - FindOutIslamNow
6
阅读评论时在我脑海中发生的对话: 我正在阅读:“我忘记把属性公开。不要忘记这样做...”, 我想:“这太愚蠢了,我不会忘记的... <检查代码> <给自己一个上钩拳>”。谢谢@KthProg - Ads
1
在我的情况下,它是 { get; internal set; } - Elfalem
1
在我的情况下,根本没有setter!该类使用构造函数参数来设置属性。 - Paul
才华横溢 - Bugbeeb

21

为了帮助其他可能遇到此问题或类似问题的人...

在我的情况下,我有一个包含其他对象数组的对象,这些子对象中的一个引用类型属性在反序列化后始终为空。我尝试了各种方法,包括下载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
}
由于在 JSON 中,Owner 属性出现在 OwnerId 属性之前,所以当设置 OwnerId 属性时,setter 代码确定当前值与要设置的值不同(因为当前值为 null),因此将 Owner 属性设置为 null。
为解决该问题,我还检查将要设置的值与 Owner 对象的 id 是否相同,如果相同则跳过将 Owner 设置为 null 的步骤。
诚然,我的问题的原因可能并非对于每个人都是相同的,但这至少是一个提醒:在反序列化期间初始化对象时,请仔细检查发生了什么情况。

请在此答案中添加更多内容,并检查您的类属性名称是否与JSON响应中的名称相同。 - LordDraagon

8
我不知道你是如何尝试反序列化的,但这应该可以解决问题...
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; }
}

1
这正是我所做的。但是,在这里,我将RootObject.Position设置为null。 - JossVAMOS
@ColombetJosselyn,我不能是相同的。鉴于您上面的JSON字符串,代码可以正常工作...当然,我已经修复了您的无效JSON :) \"Request"\ - I4V
我并没有说你的部分是不正确的,我只是说,在我的部分中也有完全相同的部分,并且它没有实例化“position”。 - JossVAMOS
@ColombetJosselyn 我说过,我已经尝试过了,我看到所有的值都被填充了.....只需复制/粘贴上面的代码并尝试.... - I4V

5
在我的情况下,我的类属性具有内部设置器,在将它们设置为public之后问题得到解决。

2
我的问题是在 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 我没有在这里看到这个答案,所以我包含它,希望它能帮助那些犯了和我一样愚蠢错误的人。

2
在我的情况下,存在一种更微妙的错误。通过错误地添加前导或尾随空格到JSON键中,很容易出现问题。当发生这种情况时,该键不被识别,并且尝试反序列化它会将其值设置为 null。
例如:{" id": 123}
由于前导空格" id",因此无法识别此id字段。要解决此问题,请将 JSON 修改为 "id"
最初的回答:在某些情况下,JSON反序列化失败可能是由于键中添加了不必要的空格而导致的。要解决此问题,请确保键中没有额外的空格。

1

我以前使用Newtonsoft.Json从来没有遇到过任何问题,但是在最新的项目中决定使用内置的json库。结果却得到了null的结果。原来以下代码会失败:

JSON:

{
   "myProperty": "abc"
}

类:

public void MyClass
{
   public string MyProperty { get; set; }
}

为什么会失败?json中的"myProperty"是驼峰式(以小写字母开头),而MyClass中的MyProperty以大写字母开头。如果将两种情况都改成相同的,它就可以工作了。我试图找出如何为整个应用程序配置大小写不敏感性,但显然这是不可能的,所以我回到了Newtonsoft.JSON,问题就解决了。

1
请确保JSON中的数组名称与您的类中的属性名称匹配。
说明(查找“组件”):
JSON:
{  
  "Components": [
    {
      "Attribute1": "ABC",
      "Attribute2": "XYZ"      
    }
  ]
}

类:

public class MyClass
{
    public IList<Component> Components { get; set; }
}

反序列化:
JsonConvert.DeserializeObject<MyClass>(File.ReadAllText(@"ComponentSet.json"))

0
在我的情况下,是因为我的类没有公共构造函数。
这是我的类最初的样子:
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)
    {
        // ...
    }
}

它运行了!


0
在我的情况下,问题是当试图将JSON中的null值转换为int时,deserializeobject返回null
    public class ItemCalcResModel
    {
        public int cartId;
    }

我通过在项目中启用nullable解决了这个问题:

    #nullable enable
    public class ItemCalcResModel
    {
        public int? cartId;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接