[System.Runtime.Serialization] Static writer fix.
authorMarcos Henrich <marcos.henrich@xamarin.com>
Mon, 29 Feb 2016 19:10:55 +0000 (19:10 +0000)
committerMarcos Henrich <marcos.henrich@xamarin.com>
Tue, 29 Mar 2016 09:09:38 +0000 (10:09 +0100)
While serializing any type into a contract member of type object an
exception would be thrown.

To avoid this XmlObjectSerializerWriteContext.InternalSerialize should
in this case be called using the object type instead of the member type,
similar how reference sources does in  type instead of the member type,
 referencesources seems to be doing omething similar [1].

Fixes #37116.

[1]
http://referencesource.microsoft.com/#System.Runtime.Serialization/System/Runtime/Serialization/XmlObjectSerializerWriteContext.cs,619

mcs/class/System.Runtime.Serialization/ReferenceSources/XmlFormatWriterGenerator_static.cs

index fdbcc77c5ba9a9dd2165481724d0e3d2285a8745..f0b6d8d669a1ad8d38cbc385a3bb10d92bf16376 100644 (file)
@@ -507,11 +507,15 @@ namespace System.Runtime.Serialization
                                                } else {
                                                        var typeHandleValue = Type.GetTypeHandle (memberValue);
                                                        var isDeclaredType = typeHandleValue.Equals (CodeInterpreter.ConvertValue (memberValue, memberType, Globals.TypeOfObject));
-                                                       if (isNullableOfT)
+                                                       if (isNullableOfT) {
                                                                ctx.InternalSerialize (writer, memberValue, isDeclaredType, writeXsiType, DataContract.GetId (memberType.TypeHandle), memberType.TypeHandle);
-                                                       else
-                                                               ctx.InternalSerializeReference (writer, memberValue, isDeclaredType, writeXsiType, DataContract.GetId (memberType.TypeHandle), memberType.TypeHandle);                                                          
-                                                       //InternalSerialize((isNullableOfT ? XmlFormatGeneratorStatics.InternalSerializeMethod : XmlFormatGeneratorStatics.InternalSerializeReferenceMethod), () => memberValue, memberType, writeXsiType);
+                                                       } else if (memberType == Globals.TypeOfObject) {
+                                                               var dataContract = DataContract.GetDataContract (memberValue.GetType());
+                                                               writer.WriteAttributeQualifiedName (Globals.XsiPrefix, DictionaryGlobals.XsiTypeLocalName, DictionaryGlobals.SchemaInstanceNamespace, dataContract.Name, dataContract.Namespace);
+                                                               ctx.InternalSerializeReference (writer, memberValue, false, false, -1, typeHandleValue);
+                                                       } else {
+                                                               ctx.InternalSerializeReference (writer, memberValue, isDeclaredType, writeXsiType, DataContract.GetId (memberType.TypeHandle), memberType.TypeHandle);
+                                                       }
                                                }
                                        }
                                }