Fadi Banna
Fadi Banna

Reputation: 554

Unable to deserialize object from xml file xamarin forms

So I'm trying to serialize and deserialize an object called player in my xamarin forms project. and thats what Player looks like:

    public class Player 
    {

        //stores weather the player ended his turn
        public bool turnOver = false;
        //the name of the player

        public string name { get; set; }
        //total score of the player

        public long score { get; set; }
        //coins to buy abillities

        public int coins { get; set; }
        //array that stores for each ability how much  uses left

        public int[] abilities = { 2, 2, 2, 2 };
        //the levels the player have completed

        public List<long> completedLevels;
        //player constructor that initializes all the data for initial use
        public Player()
        {
            this.name = "";
            score = 0;
            coins = 100;
            completedLevels = new List<long>();
        }
      }

I used these methods in the Android project to serialize and deserialize the object.

    public void Serialize<T>(Player list)
    {
            //Creating XmlSerializer.
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
            var filePath = Path.Combine(documentsPath, "data1.xml");
            var file = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.Write);
            var strm = new StreamWriter(file);
            //Convert the XML to List
            serializer.Serialize(strm, list);
            strm.Close();
    }

    public T GenericDeSerialize<T>()
    {
        //Creating XmlSerializer for the object
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
        var filePath = Path.Combine(documentsPath, "data1.xml");
        var file = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.Read);
        var strm = new StreamReader(file);
        string text = strm.ReadToEnd();
        //Deserialize back to object from XML
        T b = (T)serializer.Deserialize(strm);
        strm.Close();
        return b;

    }

Now the serialize part goes well but when trying to deserialize I get the Exception:

Root element is missing

I took a look at the generated xml and it looks like that:

    <?xml version="1.0" encoding="utf-8"?>
<Player xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <turnOver>false</turnOver>
  <abilities>
    <int>2</int>
    <int>2</int>
    <int>2</int>
    <int>2</int>
  </abilities>
  <completedLevels />
  <name />
  <score>0</score>
  <coins>500</coins>
</Player>

I can't find the problem with this can anyone point out why xmlserializer may be writing something and couldn't read it? Thanks

Edit: Here is how I call them for testing right now serializer is the class that have the two functions.

        Serializer ser = new Serializer();
        Player p = new Player();
        p.coins = 500;
        ser.Serialize<Player>(p);
       ser.GenericDeSerialize<Player>();

Upvotes: 0

Views: 597

Answers (1)

DavidS
DavidS

Reputation: 2934

During serialization, the code does this:

  XmlSerializer serializer = new XmlSerializer(typeof(T));

But during deserialization, it does this:

  XmlSerializer serializer = new XmlSerializer(typeof(List<T>));

You are trying to deserialize List< Player >, but you serialized Player, and your XML just shows one Player, not a List< Player >. You need to serialize and deserialize the same type.

EDIT

A second issue is during deserialization, the code is attempting to consume the stream twice:

    string text = strm.ReadToEnd();
    //Deserialize back to object from XML
    T b = (T)serializer.Deserialize(strm);

The strm.ReadToEnd() call will consume the stream, leaving nothing for the serializer.Deserialize call to work with. Either get rid of the strm.ReadToEnd() call (the code isn't using 'text'), deserialize from 'text', or reset the stream to the beginning between the calls.

Upvotes: 1

Related Questions