views:

472

answers:

6

It seems that serialization is very straightforward. Assuming that both the key and value are serializable, what could be simpler than representing key-value pairs in XML?!

To all the commenters: First of all, I appreciate your answers, But- I am less interested in workoraunds (There is indeed plenty of SerializableDictionary implementations on the web for picking) and more as to the reason for this design decision.

+2  A: 

This guy created an xml serializable dictionary.

Joseph
Amazing that I answered the question and got no votes. Apparently people don't read the questions anymore.
Nissan Fan
A: 

The why is simple: XmlSerializer doesn't support private members, deep serialization or fields of types without a default constructor. In short, it's pretty much useless in most scenarios.

Here's a solution that may work as an alternate option: http://sourceforge.net/projects/nxmlserializer/

Nissan Fan
It's so "useless in most scenarios" that it is used to serialize every ASMX web service ever created. Way to exaggerate.
John Saunders
You MVPs really know your stuff. Come out of the cave once in awhile for something more than a PDC and join the rest of us in using English as a first language. Most does not = all. What possible good is a serializer that doesn't truly capture the complete state of an object? Exactly.
Nissan Fan
+3  A: 

"Why" part:

Unfortunately there's no way to make XmlSerializer function with IDictionary-derived objects since the infrastructure explicitly checks for IDictionary at run time and disables serialization. One way around this is to write a new class that wraps an IDictionary object and copies the values into an array of serializable objects. The XmlSerializer framework also has a hidden hook for writing custom serialization code. To take advantage of this hook you can implement an interface called IXmlSerializable for the object you want to serialize/deserialize.

When you instantiate an XmlSerializer object, the constructor usually generates a temporary assembly containing XmlReader and XmlWriter code for moving between object instances and XML documents. Before doing this, however, it first checks to see if the supplied type derives from IXmlSerializable and if so, it generates code to call into the IXmlSerializable members instead. In other words, if you implement IXmlSerializable, you completely bypass the automatic serialization process and have the opportunity to provide your own.

You can read entire article here: XML Files: Advanced Type Mappings

Rubens Farias
this is simply reiterating the problem (design decision), not providing an answer as to the reason for it!
Tao
A: 

Use DataContract Serialization from WCF. Here is a link.

It is different from ISerializable in that it is an opt-in where as ISerializable is opt-out.

Here is a link that talks of collections with DataContract serialization.

devSpeed
+1  A: 

Presuming that your question is (too) how to serialize a Dictionary in an xml format, the partial answer is: use DataContractSerializer:

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;//you need to set a reference to System.Runtime.Serialization.dll!

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var dictionary = new Dictionary<int, string>();
            dictionary.Add(1,"John");
            dictionary.Add(2,"Jane");

            var serializer = new DataContractSerializer(typeof(Dictionary<int, string>));
            using (var stream = new FileStream("dictionary.xml", FileMode.Create, FileAccess.Write))
            {
                serializer.WriteObject(stream,dictionary);
            }

            var xml = File.ReadAllText("dictionary.xml");

            Console.WriteLine("dictionary was stored as: {0}",xml);
            Console.ReadLine();
        }
    }
}
Dabblernl
+2  A: 

Ok, you want to know why?

The XML Serializer isn't just about serializing and deserializing. It's also about serializing/deserializing XML that validates against the XML Schema that is also produced by XML Serialization.

How would you define a dictionary in XML Schema? When you do, will you maintain the semantics of unique key? If you do, will any caller be able to look at that schema definition and determine that it really means a dictionary?


I've just read Collection Types in Data Contracts and learned more about data contracts and collections than I had previously thought existed. I recommend that anyone interested in the subject read that section, the sections it references, and the related sections.

Among other things, you'll learn how the DataContractSerializer gets solves the problem of XML Schema having no way to describe a dictionary - it adds a WCF-specific annotation to the XML schema. Only code that understands that annotation will know that the schema is describing a dictionary.

John Saunders
As far as I know, the process of serialization does not produce a schema. Schema validation is a separate process made to actual Xml entities. If what you say is true- how would you explain that a DataContractSerializer actually can serialize dictionaries. In this context, the schema is of the most importance!My point is that I do not believe schema has anything to do with it.
Vitaliy
You are mistaken. See `IXmlSerializable`.
John Saunders
So to Vitaliy's point, you're saying that DataContractSerializer works because it's done away with the Xml Schema restriction?
Tao
@Tao: no, where did you get that?
John Saunders
I'm trying to reconcile your explanation (justification?) of the design decision "How would you define a dictionary in XML Schema? When you do, will you maintain the semantics of unique key? If you do, will any caller be able to look at that schema definition and determine that it really means a dictionary? [...]" with Vitaliy's question "If what you say is true- how would you explain that a DataContractSerializer actually can serialize dictionaries." and your followup - sorry, I know nothing about DataContractSerializer, I assumed there was a reason you answered only one part.
Tao
@Tao: I suggest you find out about the DataContractSerializer, as it is quite different from the XmlSerializer, and has different goals. The DataContractSerializer only "works" on dictionaries between .NET systems. It does not "work" in general, because no other system will have any idea that a dictionary is intended. At some point, it was decided to permit this non-standard hack. I don't know why, as I don't work for Microsoft.
John Saunders
Fair enough, thanks for the explanation! If I understand you correctly ANY xml that successfully validates to a DataContractSerializer or XmlSerializer Schema (excluding Dictionaries in DataContractSerializer and excluding of course any manually-defined IXmlSerializable schemas) should be deserializable, barring any class-specific constraints implemented in properties or constructors? If that's true it's pretty neat, it never occurred to me!
Tao
@Tao: pleae go read [Using Data Contracts](http://msdn.microsoft.com/en-us/library/ms733127.aspx) and [Data Contract Serializer](http://msdn.microsoft.com/en-us/library/ms731072.aspx). You are confusing yourself further by trying to infer meaning from what I said where it was not implied.
John Saunders