繁体   English   中英

如何使用JSON序列化对象列表

[英]How to serialize a list of objects with JSON

我正在开发一种软​​件来管理我的硬币收集。 我需要在JSON文件中导出对象列表的内容,但是每次我要显示数据库中实际存在的硬币时,都会遇到此错误:

阅读完JSON内容后遇到的其他文本:[。 路径'',第1行,位置109。

这是应该发生的所有地方:

List<Coin> coins = new List<Coin>();

public bool AddACoin (int ID, String coinName, String coinNation, String coinStatus, int coinYear, int quantity, float value)
{
    var jsonSerializer = new JsonSerializer();

    using (StreamWriter streamWriter = new StreamWriter(path, true))
    using (JsonWriter jsonWriter = new JsonTextWriter(streamWriter))
    {
        coins.Add(new Coin(ID, coinName, coinNation, coinStatus, coinYear, quantity, value));
        jsonSerializer.Serialize(jsonWriter, coins.ToList());
    }

    return true;
}

输出存储在方括号的不同块中。 对于插入的每个对象,我都有一个障碍。 相反,我应该将每个对象放在一个独特的方括号内。 提前致谢。

编辑:这是JSON文件的内容

[{"ID":0,"coinName":"1 Euro","coinNation":"Ita","coinStatus":"FdC","coinYear":2005,"quantity":1,"value":4.7}][{"ID":0,"coinName":"1 Euro","coinNation":"Ita","coinStatus":"FdC","coinYear":2005,"quantity":1,"value":4.7},{"ID":1,"coinName":"2 Euro","coinNation":"Bel","coinStatus":"FdC","coinYear":2004,"quantity":1,"value":30.0}]

正如我所说,所有内容都应放在方括号的唯一块内。

我认为我已经找到了解决问题的方法,并且将与您分享。 我更改了一些行,现在有:

public bool AddACoin (int ID, String coinName, String coinNation, String coinStatus, int coinYear, int quantity, float value)
    {
        var jsonSerializer = new JsonSerializer();

        using (StreamReader streamReader = new StreamReader(path, true))
        {
            string json = streamReader.ReadToEnd();
            coins = JsonConvert.DeserializeObject<List<Coin>>(json);
            coins.Add(new Coin(ID, coinName, coinNation, coinStatus, coinYear, quantity, value));
            string newJson = JsonConvert.SerializeObject(coins);
            streamReader.Close();
            File.WriteAllText(path, newJson);
        }
            return true;
    }

如果我的想法正确,执行此操作将导致程序读取直到到达EOF,然后在对列表进行序列化/反序列化之后,追加新对象。 目前,这似乎很好。

我建议您使用NewtonsoftJSON(可以通过NuGet进行安装),每次添加新硬币时都要清除json文件,以下是硬币管理器示例:

public class CoinsManager
{
    public List<Coin> Coins { get; set; }

    public string FilePath { get; set; }

    public CoinsManager(string filePath)
    {
        FilePath = filePath;
        Coins = new List<Coin>();
    }

    public void LoadCoins()
    {
        if (File.Exists(FilePath))
        {
            //If file exists, but empty, save empty settings to it
            if (new FileInfo(FilePath).Length == 0)
            {
                SaveSettings();
            }
            else
            {
                //Read json from file
                using (StreamReader r = new StreamReader(FilePath))
                {
                    string json = r.ReadToEnd();
                    //Convert json to list
                    Coins = JsonConvert.DeserializeObject<List<Coin>>(json);
                }
            }
        }
        else
        {
            //Create file
            File.Create(FilePath).Close();

            //Wait for filesystem to create file
            while (!File.Exists(FilePath))
            {
                System.Threading.Thread.Sleep(100);
            }

            //Save empty settings to file
            SaveSettings();
        }
    }

    public void SaveSettings()
    {
        string json = JsonConvert.SerializeObject(Coins);

        File.WriteAllText(FilePath, json);
    }

    //Can save or update passed coin
    public void SaveCoin(Coin coin)
    {
        //Select old coin
        var oldCoin = Coins.Where(c => c.ID == coin.ID).FirstOrDefault();

        //If there was no old coin, get last existing coin id, or zero if Coins list is empty
        if (oldCoin == null)
        {
            int lastId;
            if (Coins.Count != 0)
                lastId = Coins.Count - 1;
            else
                lastId = 0;

            coin.ID = lastId + 1;
            Coins.Add(coin);
        }
        else
        {
            int index = Coins.IndexOf(oldCoin);
            Coins[index] = coin;
        }
    }

    public void DeleteCoin(Coin coin)
    {
        Coins.RemoveAll(c => c.ID == coin.Id);
    }
}

它的用法是:

    CoinsManager coinsManager = new CoinsManager("coinsStorage.json");
    coinsManager.LoadCoins();
    coinsManager.SaveCoin(new Coin {
    ...
    });
    coinsManager.SaveSettings();

如果我理解正确,则只需更改此行:

StreamWriter streamWriter = new StreamWriter(path, true);

对此:

StreamWriter streamWriter = new StreamWriter(path, false);

您的问题是,您总是将带有所有列表的new json添加到文件中,而不仅仅是编写列表。

因为您使用的是文件,所以您需要并且想要附加的唯一选择是读取文件,然后添加元素并再次写入。

您可以在应用程序启动时阅读它,并对其进行管理,因为您的列表似乎是全局的。

或者,您可以在要写入文件之前立即阅读它。

在任何一种情况下,您都需要添加我编写的修复程序。

您可以使用它来读取列表中的json:

string myJsonString = File.ReadAllText(path);
coins = JsonConvert.DeserializeObject<List<Coin>>(myJsonString);

这是全部功能:

public bool AddACoin (int ID, String coinName, String coinNation, String coinStatus, int coinYear, int quantity, float value)
{
    var jsonSerializer = new JsonSerializer();

    using (StreamWriter streamWriter = new StreamWriter(path, false))
    using (JsonWriter jsonWriter = new JsonTextWriter(streamWriter))
    {
        string myJsonString = File.ReadAllText(path);
        coins = JsonConvert.DeserializeObject<List<Coin>>(myJsonString);
        coins.Add(new Coin(ID, coinName, coinNation, coinStatus, coinYear, quantity, value));
        jsonSerializer.Serialize(jsonWriter, coins.ToList());
    }

    return true;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM