A first chance exception of type 'System.NotSupportedException' occurred in System.Xml.dll
System.NotSupportedException: The type System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] is not supported because it implements IDictionary.
A first chance exception of type 'System.InvalidOperationException' occurred in System.Xml.dll
System.InvalidOperationException: You must implement a default accessor on System.Collections.Generic.Queue`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] because it inherits from ICollection.
at System.Xml.Serialization.TypeScope.GetDefaultIndexer(Type type, String memberInfo)
at System.Xml.Serialization.TypeScope.ImportTypeDesc(Type type, MemberInfo memberInfo, Boolean directReference)
at System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo source, Boolean directReference, Boolean throwOnError)
at System.Xml.Serialization.ModelScope.GetTypeModel(Type type, Boolean directReference)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)
A way around this problem is to implement the IXmlSerializable interface.
The following classes will allow you serialize generic types to XML in .NET 2.0:
- SerializableDictionary<T>
- SerializableLinkedList<T>
- SerializableQueue<T>
- SerializableSortedDictionary<T>
- SerializableSortedList<T>
- SerializableStack<T>
You can download the library's source code here.
The previous classes use the SerializableGenerics helper class which constructs the element name based on the key-value pair node:
/*
* SerializableGenerics
* Copyright (c) 2009, Eduardo Sanchez-Ros
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
namespace SerializableGenerics
{
public static class SerializableGenerics
{
private const string OF = "Of";
/// <summary>
/// Gets the key-value pair name
/// </summary>
/// <param name="tKey"></param>
/// <param name="tValue"></param>
/// <returns></returns>
public static string GetKeyValuePairName(Type tKey, Type tValue)
{
// return key-value pair name
return GetTypeName(tKey) + GetTypeName(tValue);
}
/// <summary>
/// Returns the name of the type
/// </summary>
/// <param name="type">Type to generate the name from</param>
/// <returns>The name of the type</returns>
public static String GetTypeName(Type type)
{
String typeName;
// Is type generic
if (type.IsGenericType)
{
// Get type name - Generics
typeName = type.Name.Substring(0, type.Name.Length - 2);
typeName += OF;
// Get type's arguments
Type[] types = type.GetGenericArguments();
foreach (Type t in types)
{
// Append type's name
typeName += GetTypeName(t);
}
}
else if (type.IsArray)
{
// Compose array name as "ArrayOf" and get array element's type name
typeName = type.BaseType.Name;
typeName += OF;
typeName += GetTypeName(type.GetElementType());
}
else
{
// Append type's name
typeName = type.Name;
}
// return type's name
return typeName;
}
}
}
You sir, are a legend.
ReplyDeleteThanks so much for posting this, you've saved hours of time and pain