'How to serialize multi-types Collection with IXmlSerializable

I'm writing an xml that seem decent to me but i have issue reading into last collection.

Xml

  <SWorkspace Title="Default" NosWorkSpaceGuid="69c4d731-a44d-4eaf-b61c-12042bfaf714">
<ChartWindow WindowsGuid="93213993-7215-4006-9e05-e30dff98b038" Top="0" Left="NaN" Height="0" Width="NaN">
<ArrayOfBaseContener xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<BaseContener ContenerGuid="393bc0e5-bce0-4446-becd-a8796f18ccb9">
<ArrayOfBaseIndicator>
<BaseIndicator Name="Ohlc" BarType="unknow" type="NosIndicator.Ohlc.Ohlc, NosIndicators, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<ArrayOfBaseRenderableSeriesViewModel>
<BaseRenderableSeriesViewModel xsi:type="CandlestickRenderableSeriesViewModel">
<IncludeRolloverModifier>true</IncludeRolloverModifier>
<IncludeTooltipModifier>true</IncludeTooltipModifier>
<IncludeSeriesValueModifier>true</IncludeSeriesValueModifier>
<IncludeSeriesSelectionModifier>true</IncludeSeriesSelectionModifier>
<IncludeDataPointSelectionModifier>true</IncludeDataPointSelectionModifier>
<IsDigitalLine>false</IsDigitalLine>
<Tag xmlns:q1="http://microsoft.com/wsdl/types/" xsi:type="q1:guid">0e2411a0-7b8f-4788-b636-122a9499a62b</Tag>
<Opacity>1</Opacity>
<IsVisible>true</IsVisible>
<AntiAliasing>true</AntiAliasing>
<Stroke>
<A>255</A>
<R>0</R>
<G>128</G>
<B>0</B>
<ScA>1</ScA>
<ScR>0</ScR>
<ScG>0.21586053</ScG>
<ScB>0</ScB>
</Stroke>
<IsSelected>false</IsSelected>
<StrokeThickness>1</StrokeThickness>
<ResamplingMode>Auto</ResamplingMode>
<XAxisId>DefaultAxisId</XAxisId>
<YAxisId>DefaultAxisId</YAxisId>
<ZeroLineY>0</ZeroLineY>
<DrawNaNAs>Gaps</DrawNaNAs>
<StrokeUp xsi:nil="true"/>
<StrokeDown xsi:nil="true"/>
<DataPointWidth>0.8</DataPointWidth>
</BaseRenderableSeriesViewModel>
</ArrayOfBaseRenderableSeriesViewModel>
</BaseIndicator>
</ArrayOfBaseIndicator>
</BaseContener>
</ArrayOfBaseContener>
</ChartWindow>
</SWorkspace>

here is my IxmlSerialization for class causing the issue.

 BaseContener Serialization:

    public void WriteXml(XmlWriter writer)
    {
    writer.WriteAttributeString(nameof(ContenerGuid), this.ContenerGuid.ToString());
                  
    XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<BaseIndicator>));          
    serializer.Serialize(writer, actifIndicators);
    }

BaseContener Deserialization:

public void ReadXml(XmlReader reader)
        {
            ContenerGuid = Guid.Parse(reader.GetAttribute(nameof(ContenerGuid)));
            OnInitialization();
            while (reader.Read())
            { 
                   switch (reader.NodeType)
                {
                   
                    case XmlNodeType.Element:
                       
                      if (reader.Name == "BaseIndicator")
                        {

                            if (!reader.HasAttributes)
                            {
                                MessageBox.Show("No Attributs");

                            }
                            else
                            {
                                string type = reader.GetAttribute("type");
                                reader.Read(); // consume the value
                                if (type != "null")
                                {
                                    XmlSerializer serializer = new XmlSerializer(Type.GetType(type));
                                    var indicator = serializer.Deserialize(reader);
                                }
                               
                            }
                        
                        }
                            break;
                }
            }
        }

For the indicator deserialisation:

  public void WriteXml(XmlWriter writer)
        {
            Type[] SuportedTypes = new Type[] { typeof(CandlestickRenderableSeriesViewModel), typeof(LineRenderableSeriesViewModel) };


            writer.WriteAttributeString(nameof(Name), this.GetType().Name);
            writer.WriteAttributeString(nameof(BarType), BarType.ToString());
            writer.WriteAttributeString("type", this.GetType().AssemblyQualifiedName);
         

             XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<BaseRenderableSeriesViewModel>) , SuportedTypes) ;
             serializer.Serialize(writer, SeriesViewModels);
}


  

public void ReadXml(XmlReader reader)
        {
            //Deserialization crash before this point
            Name = reader.GetAttribute(nameof(Name));
    
            while (reader.Read())
            {  
                
                switch (reader.NodeType)
                {
                   
                   

                }
            }
        }

the error is :

ArrayOfBaseRenderableSeriesViewModel was not expected

Any idea how to fix this?

as correction i will add the main probleme is my object is unknown in deserialization cuz baserenderableViewModel is from an other project i refenced.So i added reference to the namespace scichart that i don't own.

    XmlRootAttribute root = new XmlRootAttribute();            
    XmlAttributeOverrides Xoveride = new XmlAttributeOverrides();         
    root.Namespace = "http://schemas.abtsoftware.co.uk/scichart";
  
  

    XmlSerializer serializer = new XmlSerializer(SeriesViewModels.GetType(),Xoveride, SuportedTypes ,root, "http://schemas.abtsoftware.co.uk/scichart") ;
    serializer.Serialize(writer, SeriesViewModels);


Solution 1:[1]

Try following code :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication23
{

    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {


            XmlReader reader = XmlReader.Create(FILENAME);
            XmlSerializer serializer = new XmlSerializer(typeof(SWorkspace));
            SWorkspace sWorkspace = (SWorkspace)serializer.Deserialize(reader);

        }
    }
    public class SWorkspace
    {
        [XmlAttribute()]
        public string Title { get; set; }
        [XmlAttribute()]
        public string NosWorkSpaceGuid { get; set; }

        public ChartWindow ChartWindow { get; set; }

    }
    public class ChartWindow
    {
        [XmlAttribute()]
        public string WindowsGuid { get; set; }
        [XmlAttribute()]
        public string Top { get; set; }
        [XmlAttribute()]
        public string Height { get; set; }
        [XmlAttribute()]
        public string Left { get; set; }
        [XmlAttribute()]
        public string Width { get; set; }

        [XmlArray("ArrayOfBaseContener")]
        [XmlArrayItem("BaseContener")]
        public List<BaseContener> BaseContener { get; set; }
    }
    public class BaseContener
    {
        [XmlAttribute()]
        public string ContenerGuid { get; set; }

        [XmlArray("ArrayOfBaseIndicator")]
        [XmlArrayItem("BaseIndicator")]
        public List<BaseIndicator> BaseIndicator { get; set; }
    }
    public class BaseIndicator
    {
        [XmlArray("ArrayOfBaseRenderableSeriesViewModel")]
        [XmlArrayItem(ElementName = "BaseRenderableSeriesViewModel", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
        public List<BaseRenderableSeriesViewModel> BaseRenderableSeriesViewModel { get; set; }
    }
 
    [XmlInclude(typeof(CandlestickRenderableSeriesViewModel))]
    public class BaseRenderableSeriesViewModel
    {
    }
    public class CandlestickRenderableSeriesViewModel : BaseRenderableSeriesViewModel
    {
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1