为什么我不能再反序列化这些数据?

时间:2015-05-09 02:30:04

标签: c# .net json winforms serialization

我使用以下代码序列化一些数据并将其保存到文件:

        MemoryStream stream = new MemoryStream();
        DataContractJsonSerializer serializer = new DataContractJsonSerializer((typeof(Item)));

        Item item = ((Item)list.SelectedItems[0].Tag);
        serializer.WriteObject(stream, item);

        var filepath = Program.appDataPath + list.SelectedItems[0].Group.Name + ".group";

        stream.Position = 0;

        using (FileStream fileStream = new FileStream(filepath, FileMode.Create))
        {
            stream.WriteTo(fileStream);
        }

稍后,我正在尝试从文件中读回该数据并将其插入ListView:

    private void OpenFiles()
    {
        // DEBUG ONLY:
        // Read into memorystream and filestream.
        Console.WriteLine("Attempeting to open note.");

        bool canLoad = false;
        foreach (string file in Directory.GetFiles(Program.appDataPath))
        {
            if (file.EndsWith(".group"))
            {
                MemoryStream stream = new MemoryStream();
                DataContractJsonSerializer serializer =
                    new DataContractJsonSerializer(
                        typeof(
                        List<Item>
                        )
                        );
                using (FileStream fileStream =
                    new FileStream(
                        file,
                        FileMode.Open)
                        )
                {
                    fileStream.CopyTo(stream);
                }

                stream.Position = 0;
                //List<Withdrawal> tempWithList = new List<Withdrawal>();
                foreach (Item item in (List<Item>)serializer.ReadObject(stream))
                {
                    Console.WriteLine(item.Title + " " + item.Group.Name);
                    Item.Items.Add(item);
                }

                //Console.WriteLine("Got file \{file}");

                //if (file.EndsWith(".group"))
                //{
                //    Console.WriteLine("File is a group.");

                //    MemoryStream stream = new MemoryStream();
                //    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<Item>));

                //    using (FileStream fileStream = new FileStream(file, FileMode.Open))
                //    {
                //        fileStream.CopyTo(stream);
                //    }

                //    Console.WriteLine("Got stream");

                //    stream.Position = 0;

                //    try
                //    {
                //        Item.Items = (List<Item>)serializer.ReadObject(stream);
                //        Console.WriteLine("WTF?");
                //    }
                //    catch(Exception exception)
                //    {
                //        Console.WriteLine(exception.Message);
                //    }

                //    Console.WriteLine(Item.Items.Count);

                //    canLoad = true;
                //}
                //else Console.WriteLine("File is not a group.");
            }

            if (canLoad)
            {
                //list.Items.Clear();


                foreach (Item item in Item.Items)
                {
                    ListViewGroup group = new ListViewGroup(item.Group.Name);
                    list.Groups.Add(group);
                    list.Items.Add(
                        new ListViewItem(
                            item.Title,
                            group)
                            );

                    Console.WriteLine(item.Title + " " + item.Group.Name);
                }
            }
        }
    }

现在,上面的完全代码适用于较旧的程序(几个月前),但它不适用于新程序。我不知道为什么。我在任何地方都设置了断点,在这种情况下证明它是毫无意义的。

我从设置断点中学到的一件事是,即使流包含预期的数据,下一秒,当它被添加到列表时,它是NULL。列表中没有任何内容。我的想法已经用完了,谷歌没有多大帮助。

Group.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace Notes
{
    [DataContract]
    public class Group
    {
        [DataMember]
        public string Name { get; set; }
    }
}

Item.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace Notes
{
    [DataContract]
    [Serializable]
    public class Item : Note
    {
        [DataMember]
        public static List<Item> Items = new List<Item>();

        [DataContract]
        public enum ItemType
        {
            Group,
            Note
        }

        [DataMember]
        public ItemType Type { get; set; }

        [DataMember]
        public int Index { get; set; }
    }
}

Note.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace Notes
{
    [DataContract]
    public class Note
    {
        [DataMember]
        public string Title { get; set; }

    [DataMember]
    public string Content { get; set; }

    [DataMember]
    public Group Group;

    [DataContract]
    public enum NoteImportance
    {
        Important,
        Neutral,
        NotImportant
    }

    [DataMember]
    public NoteImportance Importance { get; set; }

    [DataMember]
    public bool Protected { get; set; }
}
}

如何反序列化这些对象/从文件中读取并将它们放入List或ListView?我已经这样做了,但由于某种原因,它已经无法使用了。

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:2)

创建.group文件时,序列化单个Item

    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Item));

    // And later
    serializer.WriteObject(stream, item);

但是当您反序列化.group文件的内容时,您尝试反序列化List<Item>

    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<Item>));

    // And later
    foreach (Item item in (List<Item>)serializer.ReadObject(stream))
    {
        Item.Items.Add(item);
    }

这些类型不匹配。但是为了反序列化先前序列化的数据,它们需要匹配 - 或者至少,如果序列化类型是反序列化类型,则不能是集合,因为集合被序列化为JSON数组而其他类被序列化为JSON对象(名称) /值对)。

由于看起来每个.group文件都有一个项目,并且您正在扫描的目录中有许多.group个文件,您可能只想这样做

    var serializer = new DataContractJsonSerializer(typeof(Item));

    // And later
    var item = (Item)serializer.ReadObject(stream);
    if (item != null)
        Item.Items.Add(item);