Fix bug 704813: just ignore members of type IEnumerable`1 without Add().
authorAtsushi Eno <atsushi@ximian.com>
Sat, 16 Jul 2011 13:48:41 +0000 (06:48 -0700)
committerAtsushi Eno <atsushi@ximian.com>
Sat, 16 Jul 2011 13:48:41 +0000 (06:48 -0700)
mcs/class/System.XML/System.Xml.Serialization/TypeData.cs
mcs/class/System.XML/System.Xml.Serialization/XmlReflectionImporter.cs
mcs/class/System.XML/Test/System.Xml.Serialization/XmlReflectionImporterTests.cs
mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTestClasses.cs

index 93b4815b62603b8831499b15eedcb6da87792187..fad04ac850ab17773276b112ec379aa9be65037a 100644 (file)
@@ -448,10 +448,13 @@ namespace System.Xml.Serialization
                };
 
 #if NET_2_0
-               private Type GetGenericListItemType (Type type)
+               internal static Type GetGenericListItemType (Type type)
                {
-                       if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof (ICollection<>))
-                               return type.GetGenericArguments () [0];
+                       if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof (IEnumerable<>)) {
+                               Type [] gatypes = type.GetGenericArguments ();
+                               if (type.GetMethod ("Add", gatypes) != null)
+                                       return gatypes [0];
+                       }
                        Type t = null;
                        foreach (Type i in type.GetInterfaces ())
                                if ((t = GetGenericListItemType (i)) != null)
index 82249ad6ac30bc7bd9b35c1ff8bf632ed59e4535..a929948c1ee36ea3dedee2f7f9bd80364e4a5726 100644 (file)
@@ -792,7 +792,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);
index 1ece8a76d82c2135ddf4a3213496c447804003e9..6dbbd2ef1233f50d34867a92bb9d202fb187e0cc 100644 (file)
@@ -12,6 +12,7 @@
 
 using System;
 using System.Collections;
+using System.IO;
 using System.Xml;
 using System.Xml.Schema;
 using System.Xml.Serialization;
@@ -1627,6 +1628,13 @@ namespace MonoTests.System.XmlSerialization
                {
                        new XmlSerializer (typeof (MyCollection));
                }
+
+               [Test]
+               public void Bug704813Type ()
+               {
+                       var xs = new XmlSerializer (typeof (Bug704813Type));
+                       xs.Serialize (TextWriter.Null, new Bug704813Type ());
+               }
 #endif
 
                public class Employee : IXmlSerializable
index f3626055bea9b8b54fbfd2fe0a2f73ef2a317928..c33f5b15ea5fcc2877cf2d3d275ad83303a6ce0b 100644 (file)
@@ -959,5 +959,13 @@ namespace MonoTests.System.Xml.TestClasses
                {
                }
        }
+
+       public class Bug704813Type
+       {
+               IEnumerable<string> foo = new List<string> ();
+               public IEnumerable<string> Foo {
+                       get { return foo; }
+               }
+       }
 }