簡體   English   中英

JSON反序列化字符串值到列表 <T> 使用Newtonsoft-構造函數arg在C#中為null

[英]JSON Deserializing string value to List<T> using Newtonsoft - constructor arg is null in C#

我正在使用Newtonsoft庫進行序列化和反序列化json對象。 參考代碼如下:

 public abstract class BaseNode
{
    [JsonConstructor]
    protected BaseNode(string [] specifications)
    {
        if (specifications == null)
        {
            throw new ArgumentNullException();
        }
        if (specifications.Length == 0)
        {
            throw new ArgumentException();
        }

        Name = specifications[0];
        Identifier = specifications[1];
        //Owner = specifications[2];
    }

    public string Name{ get; protected set; }
    public string Identifier { get; protected set; }
    public string Owner { get; protected set; }
}


public class ComputerNode: BaseNode
{
    [JsonConstructor]
    public ComputerNode(string[] specifications):base(specifications)
    {
        Owner = specifications[2];
    }
}

序列化工作正常,我可以將json格式的數據保存在文件中。 我將一個ComputerNode對象列表存儲在一個文件中。 以下代碼用於文件讀/寫操作:

public class Operation<T>
{
    public string path;

    public Operation()
    {
        var path = Path.Combine(Directory.GetCurrentDirectory(), "nodes.txt");

        if (File.Exists(path) == false)
        {
            using (File.Create(path))
            {
            }
        }
        this.path = path;
    }

    public void Write(string path, List<T> nodes)
    {
        var ser = JsonConvert.SerializeObject(nodes);

        File.WriteAllText(path, ser);
    }

    public List<T> Read(string path)
    {
        var text = File.ReadAllText(path);

        var res =  JsonConvert.DeserializeObject<List<T>>(text);
        return res;
    }

}

預期的文件讀取結果應該是文件中存儲的ComputerNode對象的列表。 但是,在反序列化-創建ComputerNode對象時,將調用正確的構造函數,但參數(string []規范)為null。

有沒有更好的方法來使用它。

請不要建議更改BaseNode.cs或ComputerNode.cs

感謝您的建議...

正確答案

被新的Json構造函數覆蓋。 在BaseNode.cs中

    [JsonConstructor]
    public BaseNode(string Owner, string Name, string Identifier)
    {
        this.Name = Name;
        this.Identifier = Identifier;
    }

和重寫Json構造函數-ComputerNode.cs

    [JsonConstructor]
    public ComputerNode(string Owner, string Name, string Identifier):base(Owner, Name, Identifier)
    {
        this.Owner = Owner;
    }

https://stackoverflow.com/a/23017892/34092指出:

重要的是,構造函數參數名稱必須與JSON對象的相應屬性名稱匹配才能正常工作。

您的構造函數參數稱為specifications JSON中沒有帶有specifications名稱的屬性。 這就是為什么將值傳遞為null的原因。

另請參見http://www.newtonsoft.com/json/help/html/JsonConstructorAttribute.htm

在實踐中,如果您跑步

var ser = JsonConvert.SerializeObject(nodes);
File.WriteAllText(path, ser);

其中節點是List <T>

然后

var text = File.ReadAllText(path);
var res =  JsonConvert.DeserializeObject<List<T>>(text);

其中res是List <T>

根據JsonConstructor文檔: http : //www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonConstructorAttribute.htm

指示JsonSerializer在反序列化該對象時使用指定的構造函數。

沒有地方會說有一個與要反序列化的字符串相關的構造函數參數。

實際上,您指定的構造函數( [JsonConstructor] )嘗試使用始終為null的參數覆蓋反序列化的結果

在你的情況下,你應該

[JsonConstructor]
protected BaseNode()
{

}

避免構造函數與反序列化交互。

恕我直言,反序列化器永遠不會(根據文檔)將參數提供給構造函數。

暫無
暫無

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

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