Kill MOONLIGHT from System.Xml.
[mono.git] / mcs / class / System.XML / System.Xml.Serialization / XmlReflectionImporter.cs
index a8c7b158894b4472636fa30263c1532cd4f2d68d..53a88a46a41f45d7fbffbb2e78b8a2a1886d5365 100644 (file)
@@ -9,7 +9,6 @@
 // Copyright (C) Tim Coleman, 2002
 // (C) 2003 Erik LeBel
 //
-
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -32,6 +31,7 @@
 //
 
 using System.Collections;
+using System.Collections.Generic;
 using System.Globalization;
 using System.Reflection;
 using System.Xml.Schema;
@@ -106,46 +106,69 @@ namespace System.Xml.Serialization {
                        XmlReflectionMember [] members,
                        bool hasWrapperElement)
                {
-//                     Reset ();       Disabled. See ChangeLog
-
-                       XmlMemberMapping[] mapping = new XmlMemberMapping[members.Length];
-                       for (int n=0; n<members.Length; n++)
-                       {
-                               XmlTypeMapMember mapMem = CreateMapMember (null, members[n], ns);
-                               mapping[n] = new XmlMemberMapping (members[n].MemberName, ns, mapMem, false);
-                       }
-                       elementName = XmlConvert.EncodeLocalName (elementName);
-                       XmlMembersMapping mps = new XmlMembersMapping (elementName, ns, hasWrapperElement, false, mapping);
-                       mps.RelatedMaps = relatedMaps;
-                       mps.Format = SerializationFormat.Literal;
-                       Type[] extraTypes = includedTypes != null ? (Type[])includedTypes.ToArray(typeof(Type)) : null;
-                       mps.Source = new MembersSerializationSource (elementName, hasWrapperElement, members, false, true, ns, extraTypes);
-                       if (allowPrivateTypes) mps.Source.CanBeGenerated = false;
-                       return mps;
+                       return ImportMembersMapping (elementName, ns, members, hasWrapperElement, true);
                }
 
 #if NET_2_0
                [MonoTODO]
-               public XmlMembersMapping ImportMembersMapping (string elementName, 
+               public
+#endif
+               XmlMembersMapping ImportMembersMapping (string elementName, 
                        string ns, 
                        XmlReflectionMember[] members, 
                        bool hasWrapperElement, 
                        bool rpc)
                {
-                       throw new NotImplementedException ();
+                       return ImportMembersMapping (elementName, ns, members, hasWrapperElement, rpc, true);
                }
 
+#if NET_2_0
                [MonoTODO]
-               public XmlMembersMapping ImportMembersMapping (string elementName, 
+               public
+#endif
+               XmlMembersMapping ImportMembersMapping (string elementName, 
                        string ns, 
                        XmlReflectionMember[] members, 
                        bool hasWrapperElement, 
                        bool rpc, 
                        bool openModel)
                {
-                       throw new NotImplementedException ();
+                       return ImportMembersMapping (elementName, ns, members, hasWrapperElement, rpc, openModel, XmlMappingAccess.Read | XmlMappingAccess.Write);
                }
+
+#if NET_2_0
+               [MonoTODO] // FIXME: handle writeAccessors, validate, and mapping access
+               public
+#endif
+               XmlMembersMapping ImportMembersMapping (string elementName, 
+                       string ns, 
+                       XmlReflectionMember[] members, 
+                       bool hasWrapperElement, 
+                       bool rpc, 
+                       bool openModel,
+                       XmlMappingAccess access)
+               {
+//                     Reset ();       Disabled. See ChangeLog
+
+                       ArrayList mapping = new ArrayList ();
+                       for (int n=0; n<members.Length; n++)
+                       {
+                               XmlTypeMapMember mapMem = CreateMapMember (null, members[n], ns);
+                               mapMem.GlobalIndex = n;
+                               mapMem.CheckOptionalValueType (members);
+                               mapping.Add (new XmlMemberMapping (members[n].MemberName, ns, mapMem, false));
+                       }
+                       elementName = XmlConvert.EncodeLocalName (elementName);
+                       XmlMembersMapping mps = new XmlMembersMapping (elementName, ns, hasWrapperElement, false, (XmlMemberMapping[])mapping.ToArray (typeof(XmlMemberMapping)));
+                       mps.RelatedMaps = relatedMaps;
+                       mps.Format = SerializationFormat.Literal;
+                       Type[] extraTypes = includedTypes != null ? (Type[])includedTypes.ToArray(typeof(Type)) : null;
+#if !NET_2_1
+                       mps.Source = new MembersSerializationSource (elementName, hasWrapperElement, members, false, true, ns, extraTypes);
+                       if (allowPrivateTypes) mps.Source.CanBeGenerated = false;
 #endif
+                       return mps;
+               }
 
                public XmlTypeMapping ImportTypeMapping (Type type)
                {
@@ -157,9 +180,9 @@ namespace System.Xml.Serialization {
                        return ImportTypeMapping (type, null, defaultNamespace);
                }
 
-               public XmlTypeMapping ImportTypeMapping (Type type, XmlRootAttribute group)
+               public XmlTypeMapping ImportTypeMapping (Type type, XmlRootAttribute root)
                {
-                       return ImportTypeMapping (type, group, null);
+                       return ImportTypeMapping (type, root, null);
                }
 
                public XmlTypeMapping ImportTypeMapping (Type type, XmlRootAttribute root, string defaultNamespace)
@@ -204,11 +227,17 @@ namespace System.Xml.Serialization {
                                        default: throw new NotSupportedException ("Type " + typeData.Type.FullName + " not supported for XML stialization");
                                }
 
+#if NET_2_0
+                               // bug #372780
+                               map.SetKey (typeData.Type.ToString ());
+#endif
                                map.RelatedMaps = relatedMaps;
                                map.Format = SerializationFormat.Literal;
                                Type[] extraTypes = includedTypes != null ? (Type[]) includedTypes.ToArray (typeof (Type)) : null;
+#if !NET_2_1
                                map.Source = new XmlTypeSerializationSource (typeData.Type, root, attributeOverrides, defaultNamespace, extraTypes);
                                if (allowPrivateTypes) map.Source.CanBeGenerated = false;
+#endif
                                return map;
                        } catch (InvalidOperationException ex) {
                                throw new InvalidOperationException (string.Format (CultureInfo.InvariantCulture,
@@ -218,12 +247,13 @@ namespace System.Xml.Serialization {
 
                XmlTypeMapping CreateTypeMapping (TypeData typeData, XmlRootAttribute root, string defaultXmlType, string defaultNamespace)
                {
-                       string rootNamespace = defaultNamespace;
+                       bool hasTypeNamespace = !string.IsNullOrEmpty (defaultNamespace);
+                       string rootNamespace = null;
                        string typeNamespace = null;
                        string elementName;
                        bool includeInSchema = true;
                        XmlAttributes atts = null;
-                       bool nullable = true;
+                       bool nullable = CanBeNull (typeData);
 
                        if (defaultXmlType == null) defaultXmlType = typeData.XmlType;
 
@@ -244,8 +274,10 @@ namespace System.Xml.Serialization {
 
                        if (atts.XmlType != null)
                        {
-                               if (atts.XmlType.Namespace != null && typeData.SchemaType != SchemaTypes.Enum)
+                               if (atts.XmlType.Namespace != null) {
                                        typeNamespace = atts.XmlType.Namespace;
+                                       hasTypeNamespace = true;
+                               }
 
                                if (atts.XmlType.TypeName != null && atts.XmlType.TypeName != string.Empty)
                                        defaultXmlType = XmlConvert.EncodeLocalName (atts.XmlType.TypeName);
@@ -259,18 +291,20 @@ namespace System.Xml.Serialization {
                        {
                                if (root.ElementName.Length != 0)
                                        elementName = XmlConvert.EncodeLocalName(root.ElementName);
-                               if (root.Namespace != null)
+                               if (root.Namespace != null) {
                                        rootNamespace = root.Namespace;
+                                       hasTypeNamespace = true;
+                               }
                                nullable = root.IsNullable;
                        }
 
-                       if (rootNamespace == null) rootNamespace = "";
-                       if (typeNamespace == null) typeNamespace = rootNamespace;
+                       rootNamespace = rootNamespace ?? defaultNamespace ?? string.Empty;
+                       typeNamespace = typeNamespace ?? rootNamespace;
                        
                        XmlTypeMapping map;
                        switch (typeData.SchemaType) {
                                case SchemaTypes.XmlSerializable:
-                                       map = new XmlSerializableMapping (elementName, rootNamespace, typeData, defaultXmlType, typeNamespace);
+                                       map = new XmlSerializableMapping (root, elementName, rootNamespace, typeData, defaultXmlType, typeNamespace);
                                        break;
                                case SchemaTypes.Primitive:
                                        if (!typeData.IsXsdType)
@@ -281,7 +315,7 @@ namespace System.Xml.Serialization {
                                                        typeData, defaultXmlType, typeNamespace);
                                        break;
                                default:
-                                       map = new XmlTypeMapping (elementName, rootNamespace, typeData, defaultXmlType, typeNamespace);
+                                       map = new XmlTypeMapping (elementName, rootNamespace, typeData, defaultXmlType, hasTypeNamespace ? typeNamespace : null);
                                        break;
                        }
 
@@ -317,14 +351,30 @@ namespace System.Xml.Serialization {
                        ClassMap classMap = new ClassMap ();
                        map.ObjectMap = classMap;
 
-                       ICollection members = GetReflectionMembers (type);
+                       var members = GetReflectionMembers (type);
+                       bool? isOrderExplicit = null;
+                       foreach (XmlReflectionMember rmember in members)
+                       {
+                               int? order = rmember.XmlAttributes.Order;
+                               if (isOrderExplicit == null)
+                               {
+                                       if (order != null)
+                                               isOrderExplicit = (int) order >= 0;
+                               }
+                               else if (order != null && isOrderExplicit != ((int) order >= 0))
+                                       throw new InvalidOperationException ("Inconsistent XML sequence was detected. If there are XmlElement/XmlArray/XmlAnyElement attributes with explicit Order, then every other member must have an explicit order too.");
+                       }
+                       if (isOrderExplicit == true)
+                               members.Sort ((m1, m2) => (int) m1.XmlAttributes.SortableOrder - (int) m2.XmlAttributes.SortableOrder);
+
                        foreach (XmlReflectionMember rmember in members)
                        {
                                string ns = map.XmlTypeNamespace;
                                if (rmember.XmlAttributes.XmlIgnore) continue;
                                if (rmember.DeclaringType != null && rmember.DeclaringType != type) {
                                        XmlTypeMapping bmap = ImportClassMapping (rmember.DeclaringType, root, defaultNamespace);
-                                       ns = bmap.XmlTypeNamespace;
+                                       if (bmap.HasXmlTypeNamespace)
+                                               ns = bmap.XmlTypeNamespace;
                                }
 
                                try {
@@ -374,8 +424,8 @@ namespace System.Xml.Serialization {
                                XmlTypeMapMember mem = classMap.XmlTextCollector;
                                if (mem.TypeData.Type != typeof(string) && 
                                   mem.TypeData.Type != typeof(string[]) && 
-                                  mem.TypeData.Type != typeof(object[]) && 
-                                  mem.TypeData.Type != typeof(XmlNode[]))
+                                  mem.TypeData.Type != typeof(XmlNode[]) && 
+                                  mem.TypeData.Type != typeof(object[]))
                                   
                                        throw new InvalidOperationException (String.Format (errSimple2, map.TypeData.TypeName, mem.Name, mem.TypeData.TypeName));
                        }
@@ -456,12 +506,16 @@ namespace System.Xml.Serialization {
 
                        foreach (XmlArrayItemAttribute att in atts.XmlArrayItems)
                        {
+                               if (att.Namespace != null && att.Form == XmlSchemaForm.Unqualified)
+                                       throw new InvalidOperationException ("XmlArrayItemAttribute.Form must not be Unqualified when it has an explicit Namespace value.");
                                if (att.NestingLevel != nestingLevel) continue;
                                Type elemType = (att.Type != null) ? att.Type : itemType;
                                XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo (null, TypeTranslator.GetTypeData(elemType, att.DataType));
                                elem.Namespace = att.Namespace != null ? att.Namespace : defaultNamespace;
                                if (elem.Namespace == null) elem.Namespace = "";
                                elem.Form = att.Form;
+                               if (att.Form == XmlSchemaForm.Unqualified)
+                                       elem.Namespace = string.Empty;
                                elem.IsNullable = att.IsNullable && CanBeNull (elem.TypeData);
                                elem.NestingLevel = att.NestingLevel;
 
@@ -596,10 +650,9 @@ namespace System.Xml.Serialization {
                        map.IsNullable = false;
                        helper.RegisterClrType (map, type, map.XmlTypeNamespace);
 
-                       string [] names = Enum.GetNames (type);
                        ArrayList members = new ArrayList();
-                       foreach (string name in names)
-                       {
+                       string [] names = Enum.GetNames (type);
+                       foreach (string name in names) {
                                FieldInfo field = type.GetField (name);
                                string xmlName = null;
                                if (field.IsDefined(typeof(XmlIgnoreAttribute), false))
@@ -641,7 +694,7 @@ namespace System.Xml.Serialization {
                        }
                }
 
-               ICollection GetReflectionMembers (Type type)
+               List<XmlReflectionMember> GetReflectionMembers (Type type)
                {
                        // First we want to find the inheritance hierarchy in reverse order.
                        Type currentType = type;
@@ -709,7 +762,7 @@ namespace System.Xml.Serialization {
                                propList.Insert(currentIndex++, prop);
                        }
 #endif
-                       ArrayList members = new ArrayList();
+                       var members = new List<XmlReflectionMember>();
                        int fieldIndex=0;
                        int propIndex=0;
                        // We now step through the type hierarchy from the base (object) through
@@ -744,7 +797,10 @@ namespace System.Xml.Serialization {
                                                XmlAttributes atts = attributeOverrides[type, prop.Name];
                                                if (atts == null) atts = new XmlAttributes (prop);
                                                if (atts.XmlIgnore) continue;
-                                               if (!prop.CanWrite && (TypeTranslator.GetTypeData (prop.PropertyType).SchemaType != SchemaTypes.Array || prop.PropertyType.IsArray)) continue;
+                                               if (!prop.CanWrite) {
+                                                       if (prop.PropertyType.IsGenericType && TypeData.GetGenericListItemType (prop.PropertyType) == null) continue; // check this before calling GetTypeData() which raises error for missing Add(). See bug #704813.
+                                                       if (TypeTranslator.GetTypeData (prop.PropertyType).SchemaType != SchemaTypes.Array || prop.PropertyType.IsArray) continue;
+                                               }
                                                XmlReflectionMember member = new XmlReflectionMember(prop.Name, prop.PropertyType, atts);
                                                member.DeclaringType = prop.DeclaringType;
                                                members.Add(member);
@@ -752,7 +808,8 @@ namespace System.Xml.Serialization {
                                        else break;
                                }
                        }
-                       return members;         
+                       
+                       return members;
                }
                
                private XmlTypeMapMember CreateMapMember (Type declaringType, XmlReflectionMember rmember, string defaultNamespace)
@@ -761,6 +818,14 @@ namespace System.Xml.Serialization {
                        XmlAttributes atts = rmember.XmlAttributes;
                        TypeData typeData = TypeTranslator.GetTypeData (rmember.MemberType);
 
+                       if (atts.XmlArray != null) {
+                               if (atts.XmlArray.Namespace != null && atts.XmlArray.Form == XmlSchemaForm.Unqualified)
+                                       throw new InvalidOperationException ("XmlArrayAttribute.Form must not be Unqualified when it has an explicit Namespace value.");
+                               if (typeData.SchemaType != SchemaTypes.Array &&
+                                   !(typeData.SchemaType == SchemaTypes.Primitive && typeData.Type == typeof (byte [])))
+                                       throw new InvalidOperationException ("XmlArrayAttribute can be applied to members of array or collection type.");
+                       }
+
                        if (atts.XmlAnyAttribute != null)
                        {
                                if ( (rmember.MemberType.FullName == "System.Xml.XmlAttribute[]") ||
@@ -771,18 +836,13 @@ namespace System.Xml.Serialization {
                                else
                                        throw new InvalidOperationException ("XmlAnyAttributeAttribute can only be applied to members of type XmlAttribute[] or XmlNode[]");
                        }
-                       else if (atts.XmlAnyElements != null && atts.XmlAnyElements.Count > 0)
+                       else
+                       if (atts.XmlAnyElements != null && atts.XmlAnyElements.Count > 0)
                        {
-                               if ( (rmember.MemberType.FullName == "System.Xml.XmlElement[]") ||
-                                        (rmember.MemberType.FullName == "System.Xml.XmlNode[]") ||
-                                        (rmember.MemberType.FullName == "System.Xml.XmlElement"))
-                               {
-                                       XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement();
-                                       member.ElementInfo = ImportAnyElementInfo (defaultNamespace, rmember, member, atts);
-                                       mapMember = member;
-                               }
-                               else
-                                       throw new InvalidOperationException ("XmlAnyElementAttribute can only be applied to members of type XmlElement, XmlElement[] or XmlNode[]");
+                               // no XmlNode type check is done here (seealso: bug #553032).
+                               XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement();
+                               member.ElementInfo = ImportAnyElementInfo (defaultNamespace, rmember, member, atts);
+                               mapMember = member;
                        }
                        else if (atts.Xmlns)
                        {
@@ -805,8 +865,8 @@ namespace System.Xml.Serialization {
                                mapAttribute.AttributeName = XmlConvert.EncodeLocalName (mapAttribute.AttributeName);
 
                                if (typeData.IsComplexType)
-                                       mapAttribute.MappedType = ImportTypeMapping (typeData.Type, null, mapAttribute.Namespace);
-                               
+                                       mapAttribute.MappedType = ImportTypeMapping (typeData.Type, null, defaultNamespace);
+
                                if (atts.XmlAttribute.Namespace != null && atts.XmlAttribute.Namespace != defaultNamespace)
                                {
                                        if (atts.XmlAttribute.Form == XmlSchemaForm.Unqualified)
@@ -837,7 +897,10 @@ namespace System.Xml.Serialization {
                                {
                                        // A flat list
 
-                                       // TODO: check that it does not have XmlArrayAttribute
+                                       // check that it does not have XmlArrayAttribute
+                                       if (atts.XmlArray != null)
+                                               throw new InvalidOperationException ("XmlArrayAttribute cannot be used with members which also attributed with XmlElementAttribute or XmlTextAttribute.");
+
                                        XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();
                                        member.ListMap = new ListMap ();
                                        member.ListMap.ItemInfo = ImportElementInfo (declaringType, XmlConvert.EncodeLocalName (rmember.MemberName), defaultNamespace, typeData.ListItemType, member, atts);
@@ -855,10 +918,18 @@ namespace System.Xml.Serialization {
                                        member.ElementInfo = new XmlTypeMapElementInfoList();
                                        XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo (member, typeData);
                                        elem.ElementName = XmlConvert.EncodeLocalName((atts.XmlArray != null && atts.XmlArray.ElementName.Length != 0) ? atts.XmlArray.ElementName : rmember.MemberName);
+                                       // note that it could be changed below (when Form is Unqualified)
                                        elem.Namespace = (atts.XmlArray != null && atts.XmlArray.Namespace != null) ? atts.XmlArray.Namespace : defaultNamespace;
                                        elem.MappedType = ImportListMapping (rmember.MemberType, null, elem.Namespace, atts, 0);
                                        elem.IsNullable = (atts.XmlArray != null) ? atts.XmlArray.IsNullable : false;
                                        elem.Form = (atts.XmlArray != null) ? atts.XmlArray.Form : XmlSchemaForm.Qualified;
+                                       elem.ExplicitOrder = (atts.XmlArray != null) ? atts.XmlArray.Order : -1;
+                                       // This is a bit tricky, but is done
+                                       // after filling descendant members, so
+                                       // that array items could be serialized
+                                       // with proper namespace.
+                                       if (atts.XmlArray != null && atts.XmlArray.Form == XmlSchemaForm.Unqualified)
+                                               elem.Namespace = String.Empty;
 
                                        member.ElementInfo.Add (elem);
                                        mapMember = member;
@@ -886,7 +957,7 @@ namespace System.Xml.Serialization {
                        Type choiceEnumType = null;
                        
                        XmlTypeMapElementInfoList list = new XmlTypeMapElementInfoList();
-                       ImportTextElementInfo (list, defaultType, member, atts);
+                       ImportTextElementInfo (list, defaultType, member, atts, defaultNamespace);
                        
                        if (atts.XmlChoiceIdentifier != null) {
                                if (cls == null)
@@ -934,9 +1005,14 @@ namespace System.Xml.Serialization {
                                elem.Form = att.Form;
                                if (elem.Form != XmlSchemaForm.Unqualified)
                                        elem.Namespace = (att.Namespace != null) ? att.Namespace : defaultNamespace;
-                               elem.IsNullable = att.IsNullable;
-                               
-                               if (elem.IsNullable && elem.TypeData.IsValueType)
+
+                               // elem may already be nullable, and IsNullable property in XmlElement is false by default
+                               if (att.IsNullable && !elem.IsNullable)
+                                       elem.IsNullable = att.IsNullable;
+
+                               elem.ExplicitOrder = att.Order;
+
+                               if (elem.IsNullable && !elem.TypeData.IsNullable)
                                        throw new InvalidOperationException ("IsNullable may not be 'true' for value type " + elem.TypeData.FullTypeName + " in member '" + defaultName + "'");
                                        
                                if (elem.TypeData.IsComplexType)
@@ -970,7 +1046,7 @@ namespace System.Xml.Serialization {
                                                        + " enumeration value '{1}' for element '{1} from"
                                                        + " namespace '{2}'.", choiceEnumType, elem.ElementName,
                                                        elem.Namespace));
-                                       elem.ChoiceValue = Enum.Parse (choiceEnumType, cname);
+                                       elem.ChoiceValue = Enum.Parse (choiceEnumType, cname, false);
                                }
                                        
                                list.Add (elem);
@@ -982,7 +1058,7 @@ namespace System.Xml.Serialization {
                {
                        XmlTypeMapElementInfoList list = new XmlTypeMapElementInfoList();
 
-                       ImportTextElementInfo (list, rmember.MemberType, member, atts);
+                       ImportTextElementInfo (list, rmember.MemberType, member, atts, defaultNamespace);
 
                        foreach (XmlAnyElementAttribute att in atts.XmlAnyElements)
                        {
@@ -999,12 +1075,13 @@ namespace System.Xml.Serialization {
                                        if (att.Namespace != null) 
                                                throw new InvalidOperationException ("The element " + rmember.MemberName + " has been attributed with an XmlAnyElementAttribute and a namespace '" + att.Namespace + "', but no name. When a namespace is supplied, a name is also required. Supply a name or remove the namespace.");
                                }
+                               elem.ExplicitOrder = att.Order;
                                list.Add (elem);
                        }
                        return list;
                }
 
-               void ImportTextElementInfo (XmlTypeMapElementInfoList list, Type defaultType, XmlTypeMapMemberElement member, XmlAttributes atts)
+               void ImportTextElementInfo (XmlTypeMapElementInfoList list, Type defaultType, XmlTypeMapMemberElement member, XmlAttributes atts, string defaultNamespace)
                {
                        if (atts.XmlText != null)
                        {
@@ -1027,6 +1104,8 @@ namespace System.Xml.Serialization {
                                 )
                                        throw new InvalidOperationException ("XmlText cannot be used to encode complex types");
 
+                               if (elem.TypeData.IsComplexType)
+                                       elem.MappedType = ImportTypeMapping (defaultType, null, defaultNamespace);
                                elem.IsTextElement = true;
                                elem.WrappedElement = false;
                                list.Add (elem);
@@ -1035,7 +1114,11 @@ namespace System.Xml.Serialization {
                
                bool CanBeNull (TypeData type)
                {
-                       return (type.SchemaType != SchemaTypes.Primitive || type.Type == typeof (string));
+#if !NET_2_0   // idiotic compatibility
+                       if (type.Type == typeof (XmlQualifiedName))
+                               return false;
+#endif
+                       return !type.Type.IsValueType || type.IsNullable;
                }
                
                public void IncludeType (Type type)
@@ -1072,7 +1155,6 @@ namespace System.Xml.Serialization {
                        string namedValue = Enum.Format (typeData.Type, defaultValue, "g");
                        // get decimal representation of enum value
                        string decimalValue = Enum.Format (typeData.Type, defaultValue, "d");
-
                        // if decimal representation matches string representation, then
                        // the value is not defined in the enum type (as the "g" format
                        // will return the decimal equivalent of the value if the value