Contract-based type must ensure that the base type is also contract-based.
authorAtsushi Eno <atsushi@ximian.com>
Thu, 20 Jan 2011 07:16:56 +0000 (16:16 +0900)
committerAtsushi Eno <atsushi@ximian.com>
Thu, 20 Jan 2011 07:16:56 +0000 (16:16 +0900)
Fixed bug #661987 on WCF side.

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

index d44a4162a06e59db2df2d8b8d7f2a1c1ae28dc7c..3cfe9d5515601b5e279495e0b6131b877f85f1c2 100755 (executable)
@@ -386,7 +386,7 @@ namespace System.Runtime.Serialization
                }
 #endif
 
-               [MonoTODO ("support arrays; support Serializable; support SharedType; use DataContractSurrogate")]
+               [MonoTODO ("use DataContractSurrogate")]
                /*
                        when writeContentOnly is true, then the input XmlWriter
                        must be at element state. This is to write possible
index 0b742de43bf1e8d0e403058eabca30480c2d773c..66fb3c52abf3ae2a068c9f86e530a65519af1e82 100755 (executable)
@@ -792,6 +792,12 @@ namespace System.Runtime.Serialization
                        contracts.Add (ret);
                        ret.Initialize ();
 
+                       if (type.BaseType != typeof (object)) {
+                               TryRegister (type.BaseType);
+                               if (!FindUserMap (type.BaseType).IsContractAllowedType)
+                                       throw new InvalidDataContractException (String.Format ("To be serializable by data contract, type '{0}' cannot inherit from non-contract and non-Serializable type '{1}'", type, type.BaseType));
+                       }
+
                        object [] attrs = type.GetCustomAttributes (typeof (KnownTypeAttribute), true);
                        for (int i = 0; i < attrs.Length; i++) {
                                KnownTypeAttribute kt = (KnownTypeAttribute) attrs [i];
index 5f1f2ac864504a4640e48a3727ceb8b0336c8a82..58f92373e8affd16ce5a828e66050ff786fa461c 100644 (file)
@@ -124,6 +124,8 @@ namespace System.Runtime.Serialization
 
                public QName XmlName { get; set; }
 
+               public abstract bool IsContractAllowedType { get; }
+
                protected void HandleId (XmlReader reader, XmlFormatterDeserializer deserializer, object instance)
                {
                        HandleId (reader.GetAttribute ("Id", KnownTypeCollection.MSSimpleNamespace), deserializer, instance);
@@ -381,6 +383,8 @@ namespace System.Runtime.Serialization
 
        internal partial class XmlSerializableMap : SerializationMap
        {
+               public override bool IsContractAllowedType { get { return true; } }
+
                public XmlSerializableMap (Type type, QName qname, KnownTypeCollection knownTypes)
                        : base (type, qname, knownTypes)
                {
@@ -419,6 +423,8 @@ namespace System.Runtime.Serialization
                {
                }
 
+               public override bool IsContractAllowedType { get { return true; } }
+
                internal void Initialize ()
                {
                        Type type = RuntimeType;
@@ -483,6 +489,8 @@ namespace System.Runtime.Serialization
                {
                }
 
+               public override bool IsContractAllowedType { get { return false; } }
+
                internal void Initialize ()
                {
                        Members.AddRange (GetDefaultMembers ());
@@ -529,6 +537,8 @@ namespace System.Runtime.Serialization
                internal override string CurrentNamespace {
                        get { return XmlName.Namespace; }
                }
+
+               public override bool IsContractAllowedType { get { return true; } }
        }
 
        internal interface ICollectionTypeMap
@@ -574,6 +584,8 @@ namespace System.Runtime.Serialization
                        return null;
                }
 
+               public override bool IsContractAllowedType { get { return false; } }
+
                public override bool OutputXsiType {
                        get { return false; }
                }
@@ -717,6 +729,8 @@ namespace System.Runtime.Serialization
                        get { return a != null && !String.IsNullOrEmpty (a.Namespace) ? a.Namespace : KnownTypeCollection.MSArraysNamespace; }
                }
 
+               public override bool IsContractAllowedType { get { return a != null; } }
+
                public Type KeyType { get { return key_type; } }
                public Type ValueType { get { return value_type; } }
 
@@ -872,6 +886,8 @@ namespace System.Runtime.Serialization
                {
                }
 
+               public override bool IsContractAllowedType { get { return true; } }
+
                public void Initialize ()
                {
                        Members = GetMembers (RuntimeType, XmlName, false);
@@ -944,6 +960,8 @@ namespace System.Runtime.Serialization
                        }
                }
 
+               public override bool IsContractAllowedType { get { return false; } }
+
                private EnumMemberAttribute GetEnumMemberAttribute (
                        MemberInfo mi)
                {
index 30e878330c838c205e02a364d13a78f4a763abbc..4a194d8daedf7e65e8781eac4e9826a9e59fb66b 100755 (executable)
@@ -1499,6 +1499,19 @@ namespace MonoTests.System.Runtime.Serialization
                        
                        var ds = (DataSet) x.ReadObject (r);
                }
+
+               [Test]
+               [ExpectedException (typeof (InvalidDataContractException))] // BaseConstraintType1 is neither DataContract nor Serializable.
+               public void BaseConstraint1 ()
+               {
+                       new DataContractSerializer (typeof (BaseConstraintType3)).WriteObject (XmlWriter.Create (TextWriter.Null), new BaseConstraintType3 ());
+               }
+
+               [Test]
+               public void BaseConstraint2 ()
+               {
+                       new DataContractSerializer (typeof (BaseConstraintType4)).WriteObject (XmlWriter.Create (TextWriter.Null), new BaseConstraintType4 ());
+               }
        }
        
        [DataContract]
@@ -1800,6 +1813,25 @@ namespace MonoTests.System.Runtime.Serialization
                [DataMember]
                public string X = "x";
        }
+
+       class BaseConstraintType1 // non-serializable
+       {
+       }
+       
+       [Serializable]
+       class BaseConstraintType2
+       {
+       }
+       
+       [DataContract]
+       class BaseConstraintType3 : BaseConstraintType1
+       {
+       }
+       
+       [DataContract]
+       class BaseConstraintType4 : BaseConstraintType2
+       {
+       }
 }
 
 [DataContract]