无法序列化和反序列化多个对象 [英] Trouble serializing and deserializing multiple objects

查看:95
本文介绍了无法序列化和反序列化多个对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用 XMLSerializer 来了解其工作原理。我能够序列化,保存和反序列化单个对象而不会出现问题。但是,当我尝试反序列化多个对象时遇到了问题。我收到此错误:未处理的异常。 System.InvalidOperationException:XML文档(10,10)中存在错误。
---> System.Xml.XmlException:意外的XML声明。 XML声明必须是文档中的第一个节点,并且不允许在其之前出现空格字符。

I currently playing with the XMLSerializerto understand how it works. I am able to serialize, save and de-serialize a single object without problem. However I run into problems when I try to de-serialize multiple objects. I get this error : Unhandled exception. System.InvalidOperationException: There is an error in XML document (10, 10). ---> System.Xml.XmlException: Unexpected XML declaration. The XML declaration must be the first node in the document, and no whitespace characters are allowed to appear before it.

我已经尝试过方法 https://stackoverflow.com/a/16416636/8964654
在这里(我可以这样做

I've tried this approach https://stackoverflow.com/a/16416636/8964654 here (and I could be doing it wrong)


 public static ICollection<T> DeserializeList<T>()
    {


      string filePath = @"TextFiles/Users.txt";
      XmlSerializer serializerTool = new XmlSerializer(typeof(User));
             List<T> list = new List<T>();


      using (FileStream fs = new FileStream (filePath, FileMode.Open)){

       while(fs.Position!=fs.Length)
       {
         //deserialize each object in the file
         var deserialized = (T)serializerTool.Deserialize(fs); 
         //add individual object to a list
         list.Add(deserialized);
        }
      }

    //return the list of objects
    return list;
}

它没用

这是我的原始代码。我特意调用了 SaveUser 方法两次,以模拟该方法在不同的时间被调用两次

This is my original code. I intentionally call the SaveUser method twice to simulate the method being called twice at different times

 [Serializable]
  public class User: ISerializable{

    public static void SaveUser(User user){
      string filePath = @"TextFiles/Users.txt";
      XmlSerializer serializerTool = new XmlSerializer(typeof(User));

      using(FileStream fs = new FileStream(filePath, FileMode.Append)){
        serializerTool.Serialize(fs, user);
        }
    }

    public static void PrintUser(){
      string filePath = @"TextFiles/Users.txt";
      XmlSerializer serializerTool = new XmlSerializer(typeof(User));

      using (FileStream fs = new FileStream (filePath, FileMode.Open)){
        User u1 = (User)serializerTool.Deserialize(fs);
        Console.WriteLine($"{u1.FirstName} {u1.LastName}, {u1.DOB.ToShortDateString()}");
        }
    }
}


class Program
    {
        static void Main(string[] args)
        {

    User user1 = new User(){
      FirstName = "Kim",
      LastName = "Styles",
      Address = "500 Penn street, Dallas, 46589",
      Username = "KimStyles@yahoo.com",
      Password ="Kim2019",
      DOB = (new DateTime(1990,10,01)),
      Id = 2
    };


     User user2 = new User(){
      FirstName = "Carlos",
      LastName = "Santana",
      Address = "500 Amigos street,San Jose, California, 46589",
      Username = "Carlos.Santana@yahoo.com",
      Password ="CarLosSan2019",
      DOB = (new DateTime(1990,10,01)),
      Id = 2
    };

   User.SaveUser(user1);
   User.SaveUser(user2);
   User.PrintUser();

        }
    }

下面是如何保存XML数据

below is how it saved XML data


<?xml version="1.0"?>
<User xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <FirstName>Kim</FirstName>
  <LastName>Styles</LastName>
  <DOBProxy>Monday, 01 October 1990</DOBProxy>
  <Username>KimStyles@yahoo.com</Username>
  <Password>Kim2019</Password>
  <Address>500 Penn street, Dallas, 46589</Address>
  <Id>1</Id>
</User>
<?xml version="1.0"?>
<User xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <FirstName>Carlos</FirstName>
  <LastName>Santana</LastName>
  <DOBProxy>Monday, 01 October 1990</DOBProxy>
  <Username>Carlos.Santana@yahoo.com</Username>
  <Password>CarLosSan2019</Password>
  <Address>500 Amigos street,San Jose, California, 46589</Address>
  <Id>2</Id>
</User>

我希望能够检索所有数据并打印每个用户的详细信息。我怎样才能做到这一点?有更好的方法吗?

I want to be able to retrieve all the data and print details of each individual user. How can I do this? Is there a better approach?

推荐答案

我将按照以下方式解决此问题:

I'd solve this problem as follow:

创建 User

Create the User class

一个可序列化类包含一个用户详细信息。

A Serializable class contains a user details.

[Serializable]
public class User
{

    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DOB { get; set; }

    public override string ToString()
    {
        return $"{ID}, {FirstName}, {LastName}, {DOB.ToShortDateString()}";
    }
}

创建用户

Create the Users class

另一个可序列化类包含 User 的列表对象并处理序列化和反序列化例程:

Another Serializable class contains a list of User objects and handles both serialize and Deserialize routines:

[Serializable]
public class Users  
{
    public List<User> ThisUsers = new List<User>();

    public void Save(string filePath)
    {
        XmlSerializer xs = new XmlSerializer(typeof(Users));

        using (StreamWriter sr = new StreamWriter(filePath))
        {
            xs.Serialize(sr, this);
        }
    }

    public static Users Load(string filePath)
    {
        Users users;
        XmlSerializer xs = new XmlSerializer(typeof(Users));
        using (StreamReader sr = new StreamReader(filePath))
        {
            users = (Users)xs.Deserialize(sr);
        }
        return users;
    }
}

这样,您可以确保XML文件的格式正确,管理用户列表(添加,删除,编辑)。

This way, you guarantee the XML file is formatted correctly, manage the users list (add, remove, edit).

保存(序列化)示例

string filePath = @"TextFiles/Users.txt";
Users users = new Users();
for (int i = 1; i < 5; i++)
{
    User u = new User
    {
        ID = i,
        FirstName = $"User {i}",
        LastName = $"Last Name {i}",
        DOB = DateTime.Now.AddYears(-30 + i)                    
    };
    users.ThisUsers.Add(u);
}
users.Save(filePath);

加载(反序列化)示例:

string filePath = @"TextFiles/Users.txt";
Users users = Users.Load(filePath);
users.ThisUsers.ForEach(a => Console.WriteLine(a.ToString()));

//Or get a specific user by id:
Console.WriteLine(users.ThisUsers.Where(b => b.ID == 3).FirstOrDefault()?.ToString());

这是生成的XML文件的样子

and here is how the generated XML file looks like

<?xml version="1.0" encoding="utf-8"?>
<Users xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ThisUsers>
    <User>
      <ID>1</ID>
      <FirstName>User 1</FirstName>
      <LastName>Last Name 1</LastName>
      <DOB>1990-11-04T08:16:09.1099698+03:00</DOB>
    </User>
    <User>
      <ID>2</ID>
      <FirstName>User 2</FirstName>
      <LastName>Last Name 2</LastName>
      <DOB>1991-11-04T08:16:09.1109688+03:00</DOB>
    </User>
    <User>
      <ID>3</ID>
      <FirstName>User 3</FirstName>
      <LastName>Last Name 3</LastName>
      <DOB>1992-11-04T08:16:09.1109688+03:00</DOB>
    </User>
    <User>
      <ID>4</ID>
      <FirstName>User 4</FirstName>
      <LastName>Last Name 4</LastName>
      <DOB>1993-11-04T08:16:09.1109688+03:00</DOB>
    </User>
  </ThisUsers>
</Users>

祝你好运。

这篇关于无法序列化和反序列化多个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆