2010-03-09 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Tue, 9 Mar 2010 11:21:24 +0000 (11:21 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Tue, 9 Mar 2010 11:21:24 +0000 (11:21 -0000)
* JsonSerializationWriter.cs, JsonSerializationReader.cs,
  JsonWriter.cs : Fix DateTime serialization and "\/" string escape
  issues. Fixed bug #586169.

* DataContractJsonSerializerTest.cs : add test for bug #586169.
* JsonWriterTest.cs : add standalone write case for "\/".

svn path=/trunk/mcs/; revision=153318

mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/ChangeLog
mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonSerializationReader.cs
mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonSerializationWriter.cs
mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonWriter.cs
mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/ChangeLog
mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs
mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/JsonWriterTest.cs

index 8a918994b3e080156dd12448de1f47051a4097f2..ff849912c093d8d7d228e60334e567b926131fd2 100644 (file)
@@ -1,3 +1,9 @@
+2010-03-09  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * JsonSerializationWriter.cs, JsonSerializationReader.cs,
+         JsonWriter.cs : Fix DateTime serialization and "\/" string escape
+         issues. Fixed bug #586169.
+
 2010-02-24  Atsushi Enomoto  <atsushi@ximian.com>
 
        * JsonWriter.cs : write NaN, INF, -INF as JSON string, not JSON number.
index 076ce33e5f07563f9966632a54705a56673c3b58..f57d2068b8cf3f1ef1ca557e519516a0b3ec6cee 100644 (file)
@@ -112,6 +112,12 @@ namespace System.Runtime.Serialization.Json
                                        return Convert.ChangeType (l, type, null);
                        case TypeCode.Boolean:
                                return reader.ReadElementContentAsBoolean ();
+                       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))
+                                       throw new XmlException ("Invalid JSON DateTime format. The value format should be '/Date(UnixTime)/'");
+                               return new DateTime (1970, 1, 1).AddMilliseconds (long.Parse (s.Substring (6, s.Length - 8)));
                        default:
                                if (type == typeof (Guid)) {
                                        return new Guid (reader.ReadElementContentAsString ());
@@ -123,7 +129,7 @@ namespace System.Runtime.Serialization.Json
                                        else
                                                return new Uri (reader.ReadElementContentAsString ());
                                } else if (type == typeof (XmlQualifiedName)) {
-                                       string s = reader.ReadElementContentAsString ();
+                                       s = reader.ReadElementContentAsString ();
                                        int idx = s.IndexOf (':');
                                        return idx < 0 ? new XmlQualifiedName (s) : new XmlQualifiedName (s.Substring (0, idx), s.Substring (idx + 1));
                                } else if (type != typeof (object)) {
index 9c7faf387c62d4a653073f8b998b82adefb79b1a..a06db4b9cacd1109e5c27fdb48388010e41c7a8d 100644 (file)
@@ -100,6 +100,9 @@ namespace System.Runtime.Serialization.Json
                                else
                                        writer.WriteString ("false");
                                break;
+                       case TypeCode.DateTime:
+                               writer.WriteString (String.Format (CultureInfo.InvariantCulture, "/Date({0})/", ((DateTime) graph).Subtract (new DateTime (1970, 1, 1)).TotalMilliseconds));
+                               break;
                        default:
                                if (graph is Guid) {
                                        goto case TypeCode.String;
index 31ceaa27ce46ba8e933e63192b75d7918581c358..f78056d9340fddd7e6528c888ce33bf8421ff184 100644 (file)
@@ -94,9 +94,9 @@ namespace System.Runtime.Serialization.Json
                                case '\\':
                                        AppendBuffer (ref sb, input, start, i, @"\\");
                                        break;
-                               //case '/':
-                               //      AppendBuffer (ref sb, input, start, i, @"\/");
-                               //      break;
+                               case '/':
+                                       AppendBuffer (ref sb, input, start, i, @"\/");
+                                       break;
                                case '\x8':
                                        AppendBuffer (ref sb, input, start, i, @"\b");
                                        break;
index d10346ea9e4dc8387be522bbc5ab4f20f7f97d37..963e608b8182b6e452ed5a52b2e265d27f1d7986 100644 (file)
@@ -1,3 +1,8 @@
+2010-03-09  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * DataContractJsonSerializerTest.cs : add test for bug #586169.
+       * JsonWriterTest.cs : add standalone write case for "\/".
+
 2010-01-27  Atsushi Enomoto  <atsushi@ximian.com>
 
        * DataContractJsonSerializerTest.cs :
index f35f3a5122ab10c754fca2be8a1a6517a922c22c..5ef864c361fb753a68e55208e2bac8d93bce5db5 100644 (file)
@@ -1342,6 +1342,25 @@ namespace MonoTests.System.Runtime.Serialization.Json
                        Assert.IsTrue (Double.IsNegativeInfinity ((double) ReadWriteObject (typeof (double), Double.NegativeInfinity, "-INF")));
                        Assert.IsTrue (Double.IsPositiveInfinity ((double) ReadWriteObject (typeof (double), Double.PositiveInfinity, "INF")));
                }
+
+               [Test]
+               public void ReadWriteDateTime ()
+               {
+                       var ms = new MemoryStream ();
+                       DataContractJsonSerializer serializer = new DataContractJsonSerializer (typeof (Query));
+                       Query query = new Query () {
+                               StartDate = DateTime.Today.ToUniversalTime().AddMonths(-1),
+                               EndDate = DateTime.Today.ToUniversalTime()
+                               };
+                       serializer.WriteObject (ms, query);
+                       Assert.AreEqual ("{\"StartDate\":\"\\/Date(1265641200000)\\/\",\"EndDate\":\"\\/Date(1268060400000)\\/\"}", Encoding.UTF8.GetString (ms.ToArray ()), "#1");
+                       ms.Position = 0;
+                       Console.WriteLine (new StreamReader (ms).ReadToEnd ());
+                       ms.Position = 0;
+                       var q = (Query) serializer.ReadObject(ms);
+                       Assert.AreEqual (query.StartDate, q.StartDate, "#2");
+                       Assert.AreEqual (query.EndDate, q.EndDate, "#3");
+               }
        }
 
        public class TestData
@@ -1506,6 +1525,14 @@ namespace MonoTests.System.Runtime.Serialization.Json
                public List<KeyValuePair<string,string>> TestData = new List<KeyValuePair<string,string>>();
        }
 
+       [DataContract] // bug #586169
+       public class Query
+       {
+               [DataMember (Order=1)]
+               public DateTime StartDate { get; set; }
+               [DataMember (Order=2)]
+               public DateTime EndDate { get; set; }
+       }
 }
 
 [DataContract]
index 765aab7386b9212f8a810859c11eab2c8ec269c3..9101f5f9bb22ac20a9f49fa308d6d06b6e626aee 100644 (file)
@@ -581,5 +581,15 @@ namespace MonoTests.System.Runtime.Serialization.Json
                        // WriteEndAttribute().
                        w.Close ();
                }
+
+               [Test]
+               public void WriteSlashEscaped ()
+               {
+                       w.WriteStartElement ("root");
+                       w.WriteString ("/my date/");
+                       w.WriteEndElement ();
+                       w.Close ();
+                       Assert.AreEqual ("\"\\/my date\\/\"", ResultString);
+               }
        }
 }