Members in the base type in different namespace are serialized in base ns.
authorAtsushi Eno <atsushi@ximian.com>
Tue, 1 Feb 2011 06:53:05 +0000 (15:53 +0900)
committerAtsushi Eno <atsushi@ximian.com>
Tue, 1 Feb 2011 06:53:05 +0000 (15:53 +0900)
When the serializer serializes a Type B which is derived from A, it used to
serialize member M in A as in namespace_of_B, not in namespace_of_A.

This should fix bug #652331.

mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.cs
mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization/XmlObjectSerializerTest.cs

index 58f92373e8affd16ce5a828e66050ff786fa461c..c76e28d257d297657cffe29b788426a74e2be2b0 100644 (file)
@@ -462,7 +462,7 @@ namespace System.Runtime.Serialization
                                if (!pi.CanRead || (!pi.CanWrite && !(map is ICollectionTypeMap)))
                                        throw new InvalidDataContractException (String.Format (
                                                        "DataMember property '{0}' on type '{1}' must have both getter and setter.", pi, pi.DeclaringType));
-                               data_members.Add (CreateDataMemberInfo (dma, pi, pi.PropertyType, qname.Namespace));
+                               data_members.Add (CreateDataMemberInfo (dma, pi, pi.PropertyType, KnownTypeCollection.GetStaticQName (pi.DeclaringType).Namespace));
                        }
 
                        foreach (FieldInfo fi in type.GetFields (flags)) {
@@ -470,7 +470,7 @@ namespace System.Runtime.Serialization
                                        GetDataMemberAttribute (fi);
                                if (dma == null)
                                        continue;
-                               data_members.Add (CreateDataMemberInfo (dma, fi, fi.FieldType, qname.Namespace));
+                               data_members.Add (CreateDataMemberInfo (dma, fi, fi.FieldType, KnownTypeCollection.GetStaticQName (fi.DeclaringType).Namespace));
                        }
 
                        return data_members;
@@ -510,7 +510,8 @@ namespace System.Runtime.Serialization
                                        continue;
                                if (mi.GetCustomAttributes (typeof (IgnoreDataMemberAttribute), false).Length != 0)
                                        continue;
-                               l.Add (CreateDataMemberInfo (new DataMemberAttribute (), mi, mt, XmlName.Namespace));
+                               string ns = KnownTypeCollection.GetStaticQName (mi.DeclaringType).Namespace;
+                               l.Add (CreateDataMemberInfo (new DataMemberAttribute (), mi, mt, ns));
                        }
                        l.Sort (DataMemberInfo.DataMemberInfoComparer.Instance);
                        return l;
@@ -908,7 +909,7 @@ namespace System.Runtime.Serialization
                                        if (fi.IsInitOnly)
                                                throw new InvalidDataContractException (String.Format ("DataMember field {0} must not be read-only.", fi));
                                        DataMemberAttribute dma = new DataMemberAttribute ();
-                                       data_members.Add (CreateDataMemberInfo (dma, fi, fi.FieldType, qname.Namespace));
+                                       data_members.Add (CreateDataMemberInfo (dma, fi, fi.FieldType, KnownTypeCollection.GetStaticQName (fi.DeclaringType).Namespace));
                                }
                        }
 
index 4a194d8daedf7e65e8781eac4e9826a9e59fb66b..98a7f792732db32c57f318869797cac5d135225b 100755 (executable)
@@ -1512,6 +1512,27 @@ namespace MonoTests.System.Runtime.Serialization
                {
                        new DataContractSerializer (typeof (BaseConstraintType4)).WriteObject (XmlWriter.Create (TextWriter.Null), new BaseConstraintType4 ());
                }
+
+               [Test] // bug #652331
+               public void MembersNamespacesInBaseType ()
+               {
+                       string xml1 = @"<Currency>JPY</Currency><Description i:nil=""true"" />";
+                       string xml2 = @"<Currency xmlns=""http://schemas.datacontract.org/2004/07/SLProto5"">JPY</Currency><Description i:nil=""true"" xmlns=""http://schemas.datacontract.org/2004/07/SLProto5"" />";
+                       Assert.AreEqual ("JPY", MembersNamespacesInBaseType_Part<SLProto5.CashAmount> (new SLProto5.CashAmount () { Currency = "JPY" }, xml1, "#1").Currency, "r#1");
+                       Assert.AreEqual ("JPY", MembersNamespacesInBaseType_Part<SLProto5_Different.CashAmount> (new SLProto5_Different.CashAmount () { Currency = "JPY" }, xml2, "#2").Currency, "r#2");
+                       Assert.AreEqual ("JPY", MembersNamespacesInBaseType_Part<SLProto5.CashAmountDC> (new SLProto5.CashAmountDC () { Currency = "JPY" }, xml1, "#3").Currency, "r#3");
+                       Assert.AreEqual ("JPY", MembersNamespacesInBaseType_Part<SLProto5_Different.CashAmountDC> (new SLProto5_Different.CashAmountDC () { Currency = "JPY" }, xml2, "#4").Currency, "r#4");
+               }
+
+               T MembersNamespacesInBaseType_Part<T> (T instance, string expectedPart, string assert)
+               {
+                       var ds = new DataContractSerializer (typeof (T));
+                       var sw = new StringWriter ();
+                       using (var w = XmlWriter.Create (sw))
+                               ds.WriteObject (w, instance);
+                       Assert.IsTrue (sw.ToString ().IndexOf (expectedPart) > 0, assert);
+                       return (T) ds.ReadObject (XmlReader.Create (new StringReader (sw.ToString ())));
+               }
        }
        
        [DataContract]
@@ -2037,4 +2058,43 @@ public class Child
        public Parent Parent;
 }
 
+namespace SLProto5
+{
+       public class CashAmount : Amount
+       {
+       }
+
+       [DataContract]
+       public class CashAmountDC : AmountDC
+       {
+       }
+
+       public class Amount
+       {
+               public string Currency { get; set; }
+               public string Description { get; set; }
+       }
+
+       [DataContract]
+       public class AmountDC
+       {
+               [DataMember]
+               public string Currency { get; set; }
+               [DataMember]
+               public string Description { get; set; }
+       }
+}
+
+namespace SLProto5_Different
+{
+       public class CashAmount : SLProto5.Amount
+       {
+       }
+
+       [DataContract]
+       public class CashAmountDC : SLProto5.AmountDC
+       {
+       }
+}
+
 #endregion