0

I have a Model with interface collection. I want to save the collection in xml file at runtime in temp location. Without interface collection the Model is saved correctly in xml file. But the interface collection in not saved in xml file. Please anyone help me to achieve this. My Model class structure is mentioned below,

MainWindowModel

public class MainWindowModel
{           
    private string header;  
    public string Header
    {
      get { return header; }
      set { header = value; }
    }

    private bool isEditing = false;
    public bool IsEditing
    {
      get { return isEditing; }
      set { isEditing = value; }
    }

    public ObservableCollection<Details> DetailsCollection { get; set; }
}

Details

public class Details
{              
   public string Key { get; set; }          
   public ObservableCollection<IValue> Values { get; set; }
}

IValue

public interface IValue
{
    int Id { get; set; }
    string Name { get; set; }
}

FileReaderWriter

public class FileReaderWriter<T>
{
   public string FileLocation;

   public T Fetch()
   {
      if (File.Exists(FileLocation))
      {
         XmlSerializer deserializer = new XmlSerializer(typeof(T));
         TextReader reader = new StreamReader(FileLocation);
         object obj = deserializer.Deserialize(reader);
         T XmlData = (T)obj;
         reader.Close();
         return XmlData;
       }
       return default(T);
    }

    public virtual string GetFileLocation()
    {
       return FileLocation;
    }

    public void Save(T model)
    {
       XmlSerializer serializer = new XmlSerializer(typeof(T));
       var directory = Path.GetDirectoryName(FileLocation);
       if (!string.IsNullOrEmpty(directory))
       {
         if (!Directory.Exists(directory))
             Directory.CreateDirectory(directory);
             using (var writer = XmlWriter.Create(FileLocation))
             {
                 serializer.Serialize(writer, model);
             }
        }
    }
}

ReaderWriterClass

    public class DetailsViewReaderWriter : FileReaderWriter<ObservableCollection<MainWindowModel>>
    {
        public DetailsViewReaderWriter()
        {
            FileLocation = ConfigurationManager.AppSettings["RecentFileLocation"];
        }
        public ObservableCollection<MainWindowModel> FetchFile()
        {
            var recentFile = Fetch();
            return recentFile;
        }
        public override string GetFileLocation()
        {
            return FileLocation;
        }
        public void SaveFile(ObservableCollection<MainWindowModel> fileModel)
        {
            Save(fileModel);
        }
    }

App.config

<appSettings>
  <add key="RecentFileLocation" value="D:\MyProject\RecentDetails.xml"/>
</appSettings>
sameer
  • 322
  • 1
  • 12
  • Take a look at this: https://stackoverflow.com/questions/1333864/xml-serialization-of-interface-property – ChristianMurschall Aug 28 '18 at 11:38
  • @linuxrocks, I am new to wpf. I referred your link but in your link they are not used Interface collection. Please give any work around on my scenario. – sameer Aug 28 '18 at 12:16

1 Answers1

0

The XmlSerializer cannot serialize Interface types. What you can do is to implement the IXmlSerializable interface. Please find below a rough! example. It is not tested. You should read carefully on how to implement the IXmlSerializable interface correctly. But to give you an idea and help to get started:

Adjust your IValue interface:

public interface IValue: IXmlSerializable
{
    int Id { get; set; }
    string Name { get; set; }
}

Implement the interface:

public class Value : IValue
{
    public int Id { get; set; }
    public string Name { get; set; }

    public XmlSchema GetSchema() => null;

    public void ReadXml(XmlReader reader)
    {
        reader.MoveToContent();
        Name = reader.GetAttribute("Name");
        Id = int.Parse(reader.GetAttribute("Id"));
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteAttributeString("Id", Id.ToString());
        writer.WriteAttributeString("Name", Name);
    }
}
ChristianMurschall
  • 1,621
  • 15
  • 26