0

Well I asked before how to write an Dictionary to an File and was referenced to http://web.archive.org/web/20100703052446/http://blogs.msdn.com/b/psheill/archive/2005/04/09/406823.aspx

So, I am trying to use it but I have the Problem that it is always generating an empty File. What am I doing wrong?

I have:

        private static void Serialize(TextWriter writer, IDictionary dictionary)
    {
        List<Entry> entries = new List<Entry>(dictionary.Count);
        foreach (object key in dictionary.Keys)
        {
            entries.Add(new Entry(key, dictionary[key]));
        }

        System.Xml.Serialization.XmlSerializer serializer = new XmlSerializer(typeof(List<Entry>));
        serializer.Serialize(writer, entries);
    }

    private static void Deserialize(TextReader reader, IDictionary dictionary)
    {
        dictionary.Clear();
        XmlSerializer serializer = new XmlSerializer(typeof(List<Entry>));
        List<Entry> list = (List<Entry>)serializer.Deserialize(reader);

        foreach (Entry entry in list)
        {
            dictionary[entry.Key] = entry.Value;
        }
    }

    public class Entry
    {
        public object Key;
        public object Value;

        public Entry()
        {
        }

        public Entry(object key, object value)
        {
            Key = key;
            Value = value;
        }
    }
}

   private void saveConfig()
    {
        TextWriter writer = File.CreateText("C:\\Users\\test.xml");
        Serialize(writer, this.configuration);
    }

   private Dictionary<String, MyConfig> configuration;

where:

 public class MyConfig{  public Item[] items=new Item[64];}

and Item.. is an pretty complex Object.

What am I doing wrong here? How get it to work? Or is it just not possible to pusth that Array in MyConfig to the FIle like that?

EDIT:

    public class Item    {    
  public Item(many params){}      
  uint whatever;
  short whatever2;
  byte bla;
  String name,
  List<Wrapper> wrappers;     
  ItemCache cache;  

 //many getters   
}

 public class ItemCache{
public ItemCache(many Params){}
List<CodeCache> cC;     
}

public class Wrapper{       
List<Cram> crams;
String name;
uint id;    
}

1 Answers1

0

The article you link to has a mistake. XmlSerializer requires that all types to be serialized are discoverable statically, in advance. The Entry class however has non-generic object keys and values, so this is not the case.

Instead, use generics, as doing so will statically specify they key and value types:

    private static void Serialize<TKey, TValue>(TextWriter writer, IDictionary<TKey, TValue> dictionary)
    {
        var entries = dictionary.Select(pair => new Entry<TKey, TValue>(pair.Key, pair.Value)).ToList();
        var serializer = new XmlSerializer(entries.GetType());
        serializer.Serialize(writer, entries);
    }

    private static void Deserialize<TKey, TValue>(TextReader reader, IDictionary<TKey, TValue> dictionary)
    {
        var serializer = new XmlSerializer(typeof(List<Entry<TKey, TValue>>));
        var list = (List<Entry<TKey, TValue>>)serializer.Deserialize(reader);

        dictionary.Clear();
        foreach (var entry in list)
        {
            dictionary[entry.Key] = entry.Value;
        }
    }

    public class Entry<TKey, TValue>
    {
        public TKey Key;
        public TValue Value;

        public Entry() { }

        public Entry(TKey key, TValue value)
        {
            Key = key;
            Value = value;
        }
    }
dbc
  • 104,963
  • 20
  • 228
  • 340
  • Hmm does that mean that the old Version is not working because the Data is added dynamically and not in the Code itself at the beginning? Unfortunately I get the same behaviour, it is generating an completly empty FIle – user3314624 Mar 05 '16 at 00:27
  • @user3314624 - if I try to use your code to serialize a dictionary, it throws an `System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type MyConfig was not expected.`. If I use the generic version, I can serialize it successfully. See https://dotnetfiddle.net/yYWyDG. The exception would explain the empty file. But your question is incomplete - it doesn't include the `Item` class. So there might be additional problems. Can you provide a [complete example](http://stackoverflow.com/help/mcve) of your problem? – dbc Mar 05 '16 at 04:12
  • I do not have access to that Class. I only can use it. But I tried to summarize the Stuff in it, although that THAT does not help :/ – user3314624 Mar 06 '16 at 04:13
  • @user3314624 - Your `Item` class as shown doesn't have a parameterless constructor. `XmlSerializer` throws an exception if any class to be serialized does not have a parameterless constructor. See https://stackoverflow.com/questions/267724/why-xml-serializable-class-need-a-parameterless-constructor. Again, you might be encountering multiple difficulties, so I'm going to suggest trying to simply your problems into multiple [mcve's](http://stackoverflow.com/help/mcve) each of which we can offer help with. – dbc Mar 06 '16 at 05:53
  • @user3314624 - also, are you catching and logging exceptions? It would be helpful if you are, and could share the complete "ToString()" output of each including the message, traceback and inner exception. – dbc Mar 06 '16 at 05:55