序列化和反序列化对象集合

Serializing and deserializing a collection of objects

我正在尝试创建一个 Rssfeed reader,它将有关播客的信息保存到 JSON 文件中,但我在对该文件进行序列化和反序列化时遇到了问题。

我意识到关于这个主题还有其他线索,但我无法掌握或理解如何将它应用到我的代码或背后的原因。

所以我有一些代码可以创建一个文件(如果它不存在)并向其中写入 JSON 数据,如下所示:

public void SaveFile(Podcast podcast)
{
    try
    {
        JsonSerializer serializer = new JsonSerializer();

        if(!File.Exists(@"C: \Users\Kasper\Desktop\Projektuppgift\Projektuppgift - Delkurs2\Projektet\Projektet\bin\Debug\podcasts.json"))
        {
            string json = JsonConvert.SerializeObject( new { Podcast = podcast });
            StreamWriter sw = File.CreateText(@"C:\Users\Kasper\Desktop\Projektuppgift\Projektuppgift-Delkurs2\Projektet\Projektet\bin\Debug\podcasts.json");
            using (JsonWriter writer = new JsonTextWriter(sw))
            {
                serializer.Serialize(writer, json);
            }
        }
        else
        {
            var filepath = @"C:\Users\Kasper\Desktop\Projektuppgift\Projektuppgift-Delkurs2\Projektet\Projektet\bin\Debug\podcasts.json";
            var jsonData = File.ReadAllText(filepath);
            var podcasts = JsonConvert.DeserializeObject<List<Podcast>>(jsonData) ?? new List<Podcast>();
            podcasts.Add(podcast);
            jsonData = JsonConvert.SerializeObject(new {PodcastList = podcasts });
            File.WriteAllText(filepath, jsonData);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("IO Exception ", ex.Message);
    }
}

我无法开始工作的是从此文件反序列化并向其添加对象。有没有一种更简单的方法可以将更多数据添加到 JSON 文件中,还是我遗漏了什么?

Podcast class 看起来像这样:

public class Podcast
{
    public string url { get; set; }

    public string name { get; set; }

    public int updateInterval { get; set; }

    public string category { get; set; }
    //public Category category = new Category();

    public List<Episode> episodes { get; set; }

    public Podcast(string url, string name, Category category, List<Episode> episodes, int updateInterval)
    {
        this.url = url;
        this.name = name;
        this.category = category.name;
        this.episodes = episodes;
        this.updateInterval = updateInterval;
    }

    public Podcast(Podcast p)
    {
        this.url = p.url;
        this.name = p.name;
        this.category = p.category;
        this.episodes = p.episodes;
        this.updateInterval = p.updateInterval;
    }
}

我还在学习 C#,但可能是您反序列化为播客列表,而当您序列化时,您正在序列化为一个对象类型。

这里似乎有几个问题:

  1. 您正在检查是否存在与您所在的文件不同的文件 reading/writing。以前的文件名中有多余的空格。避免此问题的最佳方法是使用变量来包含文件名,而不是在三个不同的地方对其进行硬编码。
  2. 您所写和阅读的 JSON 格式不一致:
    • 当您第一次创建文件时(在第一个分支中),您正在编写一个包含 属性 Podcast 的 JSON 对象,然后包含一个播客。
    • 当您尝试读取 JSON 文件时,您会将整个 JSON 视为播客列表。
    • 将新播客添加到列表后,您将 JSON 编写为包含 PodcastList 属性 的单个对象,然后包含列表。

您需要使用一致的 JSON 格式。我建议将您的代码分成更小的方法来读取和写入 podcasts.json 文件,这样更容易推理:

public static List<Podcast> ReadPodcastsFromFile(string filepath)
{
    if (!File.Exists(filepath)) return new List<Podcast>();

    string json = File.ReadAllText(filepath);
    return JsonConvert.DeserializeObject<List<Podcast>>(json);
}

public static void WritePodcastsToFile(List<Podcast> podcasts, string filepath)
{
    string json = JsonConvert.SerializeObject(podcasts);
    // This will overwrite the file if it exists, or create a new one if it doesn't
    File.WriteAllText(filepath, json);
}

然后,您可以将 SaveFile 方法简化为(我很想将其重命名为 SavePodcast):

public void SaveFile(Podcast podcast)
{
    var filepath = @"C:\Users\Kasper\Desktop\Projektuppgift\Projektuppgift-Delkurs2\Projektet\Projektet\bin\Debug\podcasts.json";
    List<Podcast> podcasts = ReadPodcastsFromFile(filepath);
    podcasts.Add(podcast);
    WritePodcastsToFile(podcasts, filepath);
}

请注意,我还从 SaveFile 中删除了异常处理。您应该将其移动到调用 SaveFile 的任何位置,以便在抛出异常时可以在该点采取适当的操作,例如:

try
{
    SaveFile(podcast);
}
catch (Exception ex)
{
    // Show a message to the user indicating that the file did not save
}