English 中文(简体)
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="ConnectionStringValue" />
     <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; }
}




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签