Merge pull request #977 from jasonleenaylor/bug-18558
authorMiguel de Icaza <miguel@gnome.org>
Tue, 10 Mar 2015 18:40:33 +0000 (14:40 -0400)
committerMiguel de Icaza <miguel@gnome.org>
Tue, 10 Mar 2015 18:40:33 +0000 (14:40 -0400)
Fix for Bug 18558

mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapMemberElement.cs
mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTests.cs

index f05ab6b2a018033bb162f01d5985b1f55f4d68df..072f9fee05c41cf681fde94a1a92ce05c474db0d 100644 (file)
@@ -83,9 +83,23 @@ namespace System.Xml.Serialization
                        else
                        {
                                if (memberValue == null)
-                                       return (XmlTypeMapElementInfo) _elementInfo[0];
-                               foreach (XmlTypeMapElementInfo elem in _elementInfo)
-                                       if (elem.TypeData.Type.IsInstanceOfType (memberValue)) return elem;
+                                       return (XmlTypeMapElementInfo) _elementInfo [0];
+                               else
+                               {
+                                       XmlTypeMapElementInfo bestTypeElem = null;
+                                       // Select the most-specific type for the given memberValue
+                                       foreach (XmlTypeMapElementInfo elem in _elementInfo)
+                                       {
+                                               if (elem.TypeData.Type.IsInstanceOfType (memberValue))
+                                               {
+                                                       if (bestTypeElem == null || elem.TypeData.Type.IsSubclassOf (bestTypeElem.TypeData.Type))
+                                                       {
+                                                               bestTypeElem = elem;
+                                                       }
+                                               }
+                                       }
+                                       return bestTypeElem;
+                               }
                        }
                        return null;
                }
index f6a0911d4fd5d4f0f66dfbfe2c42f7f00e622e0c..1c81dd737f4cc1b1eb5cbbf70c5b2705882604fe 100644 (file)
@@ -2862,7 +2862,27 @@ namespace MonoTests.System.XmlSerialization
 
 
                #endregion //GenericsSeralizationTests
+               #region XmlInclude on abstract class tests (Bug #18558)
+               [Test]
+               public void TestSerializeIntermediateType ()
+               {
+                       string expectedXml = "<ContainerTypeForTest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><XmlIntermediateType intermediate=\"false\"/></ContainerTypeForTest>";
+                       var obj = new ContainerTypeForTest();
+                       obj.MemberToUseInclude = new IntermediateTypeForTest ();
+                       Serialize (obj);
+                       Assert.AreEqual (Infoset (expectedXml), WriterText, "Serialized Output : " + WriterText);
+               }
 
+               [Test]
+               public void TestSerializeSecondType ()
+               {
+                       string expectedXml = "<ContainerTypeForTest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><XmlSecondType intermediate=\"false\"/></ContainerTypeForTest>";
+                       var obj = new ContainerTypeForTest();
+                       obj.MemberToUseInclude = new SecondDerivedTypeForTest ();
+                       Serialize (obj);
+                       Assert.AreEqual (Infoset (expectedXml), WriterText, "Serialized Output : " + WriterText);
+               }
+               #endregion
                public class XmlArrayOnInt
                {
                        [XmlArray]
@@ -3468,5 +3488,41 @@ namespace MonoTests.System.XmlSerialization
                        generationThreshold.SetValue (null, generationThresholdOld);
                        generatorFallback.SetValue (null, generatorFallbackOld);
                }
+
+#region XmlInclude on abstract class test classes
+
+               [XmlType]
+               public class ContainerTypeForTest
+               {
+                       [XmlElement ("XmlFirstType", typeof (FirstDerivedTypeForTest))]
+                       [XmlElement ("XmlIntermediateType", typeof (IntermediateTypeForTest))]
+                       [XmlElement ("XmlSecondType", typeof (SecondDerivedTypeForTest))]
+                       public AbstractTypeForTest MemberToUseInclude { get; set; }
+               }
+
+               [XmlInclude (typeof (FirstDerivedTypeForTest))]
+               [XmlInclude (typeof (IntermediateTypeForTest))]
+               [XmlInclude (typeof (SecondDerivedTypeForTest))]
+               public abstract class AbstractTypeForTest
+               {
+               }
+
+               public class IntermediateTypeForTest : AbstractTypeForTest
+               {
+                       [XmlAttribute (AttributeName = "intermediate")]
+                       public bool IntermediateMember { get; set; }
+               }
+
+               public class FirstDerivedTypeForTest : AbstractTypeForTest
+               {
+                       public string FirstMember { get; set; }
+               }
+
+               public class SecondDerivedTypeForTest : IntermediateTypeForTest
+               {
+                       public string SecondMember { get; set; }
+               }
+#endregion
+
        }
 }