开发者

How to Deserialise Xml into a Dictionary<int,string> object?

Is it possible to Deserialize the following piece of XML into a Dictionary<int,string> object?

XML:

<Config>

<DatabaseConnections>
     <Connection Name="Source Connection" Value="Connect开发者_如何学GoionStringValue" />
     <Connection Name="Target Connection" Value="ConnectionStringValue" />
<DatabaseConnections>

<Config>

I have a class which will have a property of Dictionary<int,string> {get;set;}

I would like to use the following C# code to do this:

XmlSerializer xs = new XmlSerializer(typeof(Config));

using(StringReader sr = new StringReader(rootnode.OuterXml))
{
      return (Config)xs.Deserialize(sr);
}

Are there any alternatives to doing this?


You cannot use the default XmlSerializer implementation to (de)serialize IDictionary objects to Xml. From the MSDN XmlSerializer documentation:

The XmlSerializer gives special treatment to classes that implement IEnumerable or ICollection. A class that implements IEnumerable must implement a public Add method that takes a single parameter. The Add method's parameter must be of the same type as is returned from the Current property on the value returned from GetEnumerator, or one of that type's bases.

The Dictionary<> class implements both interfaces, but does not have an Add method that takes a single parameter, so it fails.

More to the point, the xml serialization code explicitly disallows classes that implement IDictionary (from Reflector, looking at TypeScope.GetDefaultIndexer):

 if (typeof(IDictionary).IsAssignableFrom(type)) {
        if (memberInfo == null) {
            throw new NotSupportedException(...);
        }
        throw new NotSupportedException(...);
 }

So you can't even make the work by subclassing Dictionary<> and adding the required Add overload.

The article Generic Dictionaries vs. the XmlSerializer describes one workaround:

  1. First, decorate the Dictionary property with an XmlIgnore attribute. This tells the XmlSerializer to ignore that property, eliminating the reflection error.
  2. Create a new public property that takes and returns an array of DictionaryEntry objects. I tend to name these specially (_x_DictionaryName) so that it is clear one should not generally use this property.
  3. Serialize away.


You can use this class: SerializableDictionary.

You will need to change the property type, of course:

public class Config
{
     public SerializableDictionary<String, String> DatabaseConnections
     { get; set; }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜