簡體   English   中英

Json.NET JsonConvert.DeserializeObject() 返回值 null

[英]Json.NET JsonConvert.DeserializeObject() return null value

我試圖反序列化這個字符串:

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);

適用於“廣告”但不能實例化“位置”。 任何的想法?

我忘了公開這些屬性。 不要忘記這樣做...

為了幫助可能遇到此問題或與之相關的其他人...

就我而言,我有一個包含其他對象數組的對象,並且這些子對象上的一個引用類型屬性在反序列化后始終為空。 我嘗試了各種方法,包括下載 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
}

發生的事情是,因為Owner屬性出現在OwnerId屬性之前的 JSON 中,當設置OwnerId屬性時,setter 代碼確定當前值與正在設置的值不同(因為當前值是null),因此它將Owner屬性設置為 null。

為了修復它,我還檢查了針對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; }
}

確保 JSON 中的數組名稱與類中的屬性名稱匹配

說明(尋找“組件”):

JSON:

{  
  "Components": [
    {
      "Attribute1": "ABC",
      "Attribute2": "XYZ"      
    }
  ]
}

班級:

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

反序列化:

JsonConvert.DeserializeObject<MyClass>(File.ReadAllText(@"ComponentSet.json"))

就我而言,有一個更微妙的錯誤。 很容易錯誤地在 json 鍵中添加前導或尾隨空格。 發生這種情況時,無法識別鍵並嘗試反序列化它會將值設置為 null。

例如: {" id": 123}
由於前導空格" id"無法識別此id字段。 要修復它,請修復 json 以改為使用"id"

我的問題是我在 JSON 字符串的開頭包含了類名。 我從另一個類的序列化輸出中復制粘貼,其中包含我想要反序列化的類,並且我故意包含類名,認為這是正確的 JSON 字符串。 一旦我從我的 JSON 字符串中刪除了類名,它就可以很好地反序列化。

這篇文章有助於實現這一點: https : //social.msdn.microsoft.com/Forums/windowsapps/en-US/4d766a28-ff38-477f-8abf-48ed01f74cd2/jsonconvertdeserializeobjectlttgtjsonstring-returning-all-propertieslttgt-as-null?論壇= wpdevelop

我在這里沒有看到這個答案,所以我把它包括在內,希望它能幫助那些和我犯同樣愚蠢錯誤的人。

就我而言,我的類屬性有內部設置器,將它們設置為公開后,問題就解決了。

我在使用 Newtonsoft.Json 時從未遇到過任何問題,但決定在最新項目中使用內置的 json 庫。 以空結果結束。 事實證明以下將失敗:

JSON:

{
   "myProperty": "abc"
}

班級:

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

為什么會失敗? json 中的“myProperty”是駝峰式(以小寫字母開頭),而 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)
    {
        // ...
    }
}

它奏效了!

在我的例子中,問題是當嘗試將null值從 json 轉換為int時, deserializeobject化對象返回null

    public class ItemCalcResModel
    {
        public int cartId;
    }

我通過在項目中啟用nullable解決了這個問題:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM