Search code examples
c#xml-serializationxml-deserializationinvalidoperationexception

Getting InvalidOperationException when Deserializing in C#


I'm using an XML based .config file for storing some records. My XML is below:

    <?xml version="1.0" encoding="utf-8"?>
    <Data_List xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <Configuration>
        <Name>1st Week</Name>
        <Binary>
          <Field>field1</Field>
          <Version>1.0</Version>
        </Binary>
        <Binary>
          <Field>field2</Field>
          <Version>2.0</Version>
        </Binary>
    </Configuration>
      <Configuration>
        <Name>2nd Week</Name>
        <Binary>
          <Field>field1</Field>
          <Version>2.0</Version>
        </Binary>
        <Binary>
          <Field>field2</Field>
          <Version>4.0</Version>
        </Binary>
    </Configuration>
</Data_List>

I'm using C# code as follows:

public Binary
{
public String Field;
public String Version;
}

public Configuration
{
public String Name;
public List<Binary> Binary_List = new List<Binary>();

public GetfromXML()
{
List<Configuration> lists = new List<Configuration>();
TextReader reader = new StreamReader("Data_List.config");
XmlSerializer serializer = new XmlSerializer(typeof(List<Configuration>));
lists=(List<Configuration>)serializer.Deserialize(reader);
reader.Close();
}

I'm getting an exception saying "There's an error in XML document(2,2)". How can I fix it?


Solution

  • I think the problem is that your model is not well structurized. In other words, serializer does not know how to read your .xml.

    Your xml is wrong. When you have List< T > there would be an:

        <ArrayOfT></ArrayOfT>
    

    in .XML. Here is how you need to do it!

    1. First, try using xml attributes from System.Xml.Serialization(i.e. [XmlArray()])

    2. It would be better that you use FileStream instead of just pointing out URI

       using(var filestream = new FileStream(//your uri, FIleMode.Open)
      {
      }
      
    3. Use properties instead of variables. Because later on you may want to bind.

    Example of my code how i managed to solve that issue:

    public ServiceMap Deserialize()
        {
            ServiceMap serviceMap = new ServiceMap();
    
            try
            {
                using (var fileStream = new FileStream(Settings.ServiceMapPath, FileMode.Open))
                {
                    XmlReaderSettings settings = new XmlReaderSettings();
                    settings.IgnoreComments = true;
    
                    using (XmlReader reader = XmlReader.Create(fileStream, settings))
                    {
                        serviceMap = _serializer.Deserialize(reader) as ServiceMap;
                    }
                }
            }
            catch (FileNotFoundException)
            {
                MessageBox.Show("File 'ServiceMap.xml' could not be found!");
            }
    
            return serviceMap;
        }
    

    My ServiceMap class:

        [XmlRoot("ServiceMap")]
    public class ServiceMap
    {
        [XmlArray("Nodes")]
        [XmlArrayItem("Node")]
        public List<Node> Nodes = new List<Node>();
    
        [XmlArray("Groups")]
        [XmlArrayItem("Group")]
        public List<Group> Groups = new List<Group>();
    
        [XmlArray("Categories")]
        [XmlArrayItem("Category")]
        public List<Category> Categories = new List<Category>();
    }
    

    EDIT: My XML:

    <?xml version="1.0" encoding="utf-8"?>
    <ServiceMap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://   www.w3.org/2001/XMLSchema">
      <Nodes>
        <Node Name="Predrag">
      <Children>
        <Child>dijete1</Child>
        <Child>dijete2</Child>
        <Child>dijete3</Child>
        <Child>dijete4</Child>
      </Children>
      <Parents>
        <Parent>roditelj1</Parent>
        <Parent>roditelj2</Parent>
        <Parent>roditelj3</Parent>
      </Parents>
      <Group Name="Grupa" />
      <Category Name="Kategorija" />
    </Node>
    <Node Name="Tami">
      <Children>
        <Child>dijete1</Child>
        <Child>dijete2</Child>
      </Children>
      <Parents>
        <Parent>roditelj1</Parent>
      </Parents>
      <Group Name="Grupa2" />
      <Category Name="Kategorija2" />
    </Node>