[System.ServiceModel.Web] Support `null` as value for `DateTime?` field.
authorJonathan Pryor <jonpryor@vt.edu>
Wed, 4 Jan 2012 21:31:55 +0000 (16:31 -0500)
committerJonathan Pryor <jonpryor@vt.edu>
Wed, 4 Jan 2012 21:35:02 +0000 (16:35 -0500)
Fixes assistly #5863.

mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonSerializationReader.cs
mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs

index 3a5e57ff125906bcbbb5e7a3c1ba5b19600396be..d15a4733fc86bdf4690ac093e06637ac911ea642 100644 (file)
@@ -72,9 +72,12 @@ namespace System.Runtime.Serialization.Json
                        if (serialized_object_count ++ == serializer.MaxItemsInObjectGraph)
                                throw SerializationError (String.Format ("The object graph exceeded the maximum object count '{0}' specified in the serializer", serializer.MaxItemsInObjectGraph));
 
-                       if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof (Nullable<>))
+                       bool nullable = false;
+                       if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof (Nullable<>)) {
+                               nullable = true;
                                type = Nullable.GetUnderlyingType (type);
-                       
+                       }
+
                        bool isNull = reader.GetAttribute ("type") == "null";
 
                        switch (Type.GetTypeCode (type)) {
@@ -122,8 +125,11 @@ namespace System.Runtime.Serialization.Json
                        case TypeCode.DateTime:
                                // it does not use ReadElementContentAsDateTime(). Different string format.
                                var s = reader.ReadElementContentAsString ();
-                               if (s.Length < 2 || !s.StartsWith ("/Date(", StringComparison.Ordinal) || !s.EndsWith (")/", StringComparison.Ordinal))
+                               if (s.Length < 2 || !s.StartsWith ("/Date(", StringComparison.Ordinal) || !s.EndsWith (")/", StringComparison.Ordinal)) {
+                                       if (nullable)
+                                               return null;
                                        throw new XmlException ("Invalid JSON DateTime format. The value format should be '/Date(UnixTime)/'");
+                               }
 
                                // The date can contain [SIGN]LONG, [SIGN]LONG+HOURSMINUTES or [SIGN]LONG-HOURSMINUTES
                                // the format for HOURSMINUTES is DDDD
index 2a75876fd0d5f8ce54c51d3b260a8a6edcb44c9d..7a37a5b4e7090baae46aa81d967aebd5672f9a28 100644 (file)
@@ -1385,6 +1385,17 @@ namespace MonoTests.System.Runtime.Serialization.Json
                        DateTest t = serializer.ReadObject(inputStream) as DateTest;
                        Assert.AreEqual (634129344000000000, t.ShouldHaveValue.Value.Ticks, "#1");
                }
+
+               [Test]
+               public void NullableFieldsShouldSupportNullValue ()
+               {
+                       string json = @"{""should_have_value"":null}";
+                       var inputStream = new MemoryStream (Encoding.UTF8.GetBytes (json));
+                       DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(DateTest));
+                       Console.WriteLine ("# serializer assembly: {0}", serializer.GetType ().Assembly.Location);
+                       DateTest t = serializer.ReadObject (inputStream) as DateTest;
+                       Assert.AreEqual (false, t.ShouldHaveValue.HasValue, "#2");
+               }
                
                [Test]
                public void DeserializeNullMember ()