[System.XML]: Do not set XmlTypeMapElementInfo.IsNullable if it's already True
authorAndres G. Aragoneses <knocte@gmail.com>
Wed, 3 Oct 2012 11:08:16 +0000 (12:08 +0100)
committerAndres G. Aragoneses <knocte@gmail.com>
Wed, 3 Oct 2012 11:08:16 +0000 (12:08 +0100)
The IsNullable attribute in XmlElementAttribute is false by default,
so when not using it in a member which was already nullable
(i.e. Nullable<DateTime>), Mono was overriding the attribute causing
a FormatException later if an xsi:nil value was found when deserializing.

Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=7613

mcs/class/System.XML/System.Xml.Serialization/XmlReflectionImporter.cs
mcs/class/System.XML/Test/System.Xml.Serialization/DeserializeTests.cs

index ce274821b43cffc63007c9d0d495cd85b0926caa..e9888f114846eb2810678365ab9a6c7fb75419d6 100644 (file)
@@ -9,7 +9,6 @@
 // Copyright (C) Tim Coleman, 2002
 // (C) 2003 Erik LeBel
 //
-
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -1017,7 +1016,11 @@ namespace System.Xml.Serialization {
                                elem.Form = att.Form;
                                if (elem.Form != XmlSchemaForm.Unqualified)
                                        elem.Namespace = (att.Namespace != null) ? att.Namespace : defaultNamespace;
-                               elem.IsNullable = att.IsNullable;
+
+                               // elem may already be nullable, and IsNullable property in XmlElement is false by default
+                               if (att.IsNullable && !elem.IsNullable)
+                                       elem.IsNullable = att.IsNullable;
+
                                elem.ExplicitOrder = att.Order;
 
                                if (elem.IsNullable && !elem.TypeData.IsNullable)
index 90f16f0899c9b544e613ac44511adf9da60922f3..459620cb13f8ee748e29c6b87d3aa3c5b2b3c983 100644 (file)
@@ -4,9 +4,11 @@
 // Author:
 //     Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
 //     Hagit Yidov <hagity@mainsoft.com>
+//     Andres G. Aragoneses <andres.aragoneses@7digital.com>
 //
 // (C) 2003 Atsushi Enomoto
 // (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
+// (C) 2012 7digital Media Ltd (http://www.7digital.com)
 //
 //
 using System;
@@ -1553,5 +1555,71 @@ namespace MonoTests.System.XmlSerialization
                        NotExactDateParseClass o = (NotExactDateParseClass) xs.Deserialize (new StringReader ("<NotExactDateParseClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SomeDate xsi:type=\"xsd:date\">2012-02-05-09:00</SomeDate></NotExactDateParseClass>"));
                        Assert.AreEqual (new DateTime (2012,2,5), o.SomeDate);
                }
+
+
+               public class Foo
+               {
+                       public DateTime? Baz { get; set; }
+               }
+
+               [Test]
+               public void CanDeserializeXsiNil()
+               {
+                       var reader = new StringReader(
+@"<Foo xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">
+       <Baz xsi:nil=""true"" />
+</Foo>");
+
+                       using (var xmlReader = new XmlTextReader(reader))
+                       {
+                               var serializer = new XmlSerializer(typeof(Foo));
+                               var foo = (Foo)serializer.Deserialize(xmlReader);
+                               Assert.IsNull(foo.Baz);
+                       }
+               }
+
+               public class Bar
+               {
+                       [XmlElement("baz")]
+                       public DateTime? Baz { get; set; }
+               }
+
+               [Test]
+               public void CanDeserializeXsiNilToAPropertyWithXmlElementAttrib()
+               {
+                       var reader = new StringReader(
+@"<Bar xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">
+       <baz xsi:nil=""true"" />
+</Bar>");
+
+                       using (var xmlReader = new XmlTextReader(reader))
+                       {
+                               var serializer = new XmlSerializer(typeof(Bar));
+                               var bar = (Bar)serializer.Deserialize(xmlReader);
+                               Assert.IsNull(bar.Baz);
+                       }
+               }
+
+               public class FooBar
+               {
+                       [XmlElement("baz", IsNullable = true)]
+                       public DateTime? Baz { get; set; }
+               }
+
+               [Test]
+               public void CanDeserializeXsiNilToAPropertyWithXmlElementAttribAndIsNullableTrue()
+               {
+                       var reader = new StringReader(
+@"<FooBar xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">
+       <baz xsi:nil=""true"" />
+</FooBar>");
+
+                       using (var xmlReader = new XmlTextReader(reader))
+                       {
+                               var serializer = new XmlSerializer(typeof(FooBar));
+                               var foobar = (FooBar)serializer.Deserialize(xmlReader);
+                               Assert.IsNull(foobar.Baz);
+                       }
+               }
        }
 }