无法序列化和反序列化多个对象

无法序列化和反序列化多个对象

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

问题描述

我目前正在使用 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.

我已经尝试过方法
在这里(我可以这样做

I've tried this approach https://stackoverflow.com/a/16416636/8964654here (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 = "[email protected]",
      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 = "[email protected]",
      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>[email protected]</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>[email protected]</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>

祝你好运。

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

07-29 13:34