2 // JavaScriptSerializer.cs
5 // Konstantin Triger <kostat@mainsoft.com>
7 // (C) 2007 Mainsoft, Inc. http://www.mainsoft.com
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Collections.Generic;
33 using NUnit.Framework;
34 using System.Web.Script.Serialization;
35 using System.Reflection;
36 using System.Collections;
38 using ComponentModel = System.ComponentModel;
39 using System.Globalization;
40 using System.Threading;
41 using System.Text.RegularExpressions;
42 using System.ComponentModel;
43 using CategoryAttribute = NUnit.Framework.CategoryAttribute;
44 using System.Web.UI.WebControls;
45 using System.Collections.ObjectModel;
48 namespace MonoTests.System.Web.Script.Serialization
51 public class JavaScriptSerializerTest
59 #pragma warning disable 659
63 //public DateTime dt1;
64 //public DateTime dt2;
69 //dt = DateTime.MaxValue;
70 //dt1 = DateTime.MinValue;
71 //dt2 = new DateTime ((DateTime.Now.Ticks / 10000) * 10000);
73 //hash = new Hashtable ();
74 //hash.Add ("mykey", 1);
77 public override bool Equals (object obj) {
80 JavaScriptSerializerTest.FieldsEqual (this, obj);
90 Y [] _yyy = new Y [] { new Y (), new Y () };
126 public Nullable<bool> nb;
128 IEnumerable<int> enum_int;
129 IEnumerable enum_int1;
131 public Dictionary<string, Y> hash;
134 public void Init () {
136 _bb = ulong.MaxValue - 5;
137 _yy = new Y [] { new Y (), new Y () };
141 str = "\uFF56\uFF57\uF58FF59g";
144 sh = short.MinValue + 28;
145 ush = ushort.MaxValue - 24;
147 ui = uint.MaxValue - 234234;
148 l = long.MinValue + 28;
149 ul = ulong.MaxValue - 3;
152 f1 = float.NegativeInfinity;
153 f2 = float.PositiveInfinity;
158 d1 = double.NegativeInfinity;
159 d2 = double.PositiveInfinity;
160 d3 = double.MinValue;
161 d4 = double.MaxValue;
163 de = decimal.MinusOne;
166 de3 = decimal.MinValue;
167 de4 = decimal.MaxValue;
169 g = new Guid (234, 2, 354, new byte [] { 1, 2, 3, 4, 5, 6, 7, 8 });
174 enum_int = new List<int> (MyEnum);
175 enum_int1 = new ArrayList ();
176 foreach (object obj in MyEnum1)
177 ((ArrayList) enum_int1).Add (obj);
178 uri = new Uri ("http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d", UriKind.RelativeOrAbsolute);
180 hash = new Dictionary<string, Y> ();
183 point = new Point (150, 150);
186 public IEnumerable<int> MyEnum {
198 public IEnumerable MyEnum1 {
228 public override bool Equals (object obj) {
231 JavaScriptSerializerTest.FieldsEqual (this, obj);
246 public override bool Equals (object obj) {
249 JavaScriptSerializerTest.FieldsEqual(this, obj);
266 [TypeConverter (typeof (MyUriConverter))]
269 public MyUri (string uriString, UriKind uriKind)
270 : base (uriString, uriKind) {
273 public MyUri (Uri value)
274 : base (value.AbsoluteUri) {
278 class MyUriConverter : UriTypeConverter
280 public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
282 return base.ConvertTo (context, culture, value, destinationType);
285 public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object value)
287 Uri convertedUri = (Uri)base.ConvertFrom (context, culture, value);
288 return new MyUri (convertedUri);
292 [TypeConverter(typeof(MyPointConverter))]
293 class MyPointContainer
295 public MyPointContainer ()
299 public MyPointContainer (Point v)
307 class MyPointConverter : TypeConverter
309 public override bool CanConvertTo (ITypeDescriptorContext context, Type destinationType)
311 if (destinationType == typeof (string)) {
314 return base.CanConvertTo (context, destinationType);
317 public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
319 if (destinationType == typeof (string)) {
320 MyPointContainer pc = (MyPointContainer) value;
321 return pc.p.X + "," + pc.p.Y;
323 return base.ConvertTo (context, culture, value, destinationType);
326 public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType)
328 if (sourceType == typeof (string)) {
331 return base.CanConvertFrom (context, sourceType);
334 public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object value)
336 if (value is string) {
337 string [] v = ((string) value).Split (new char [] { ',' });
338 return new MyPointContainer(new Point (int.Parse (v [0]), int.Parse (v [1])));
340 return base.ConvertFrom (context, culture, value);
344 #pragma warning restore 659
347 [Category ("NotDotNet")]
348 public void TestDefaults () {
349 JavaScriptSerializer ser = new JavaScriptSerializer ();
350 Assert.AreEqual (2097152, ser.MaxJsonLength);
351 Assert.AreEqual (100, ser.RecursionLimit);
352 //List<JavaScriptConverter> l = new List<JavaScriptConverter> ();
353 //l.Add (new MyJavaScriptConverter ());
354 //ser.RegisterConverters (l);
355 //string x = ser.Serialize (new X [] { new X (), new X () });
356 //string s = ser.Serialize (new X());
357 //"{\"BB\":10,\"__type\":\"Tests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, Tests, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null\"}"
358 //X x = ser.Deserialize<X> (s);
359 //object ddd = typeof (Y).GetMember ("BB");
360 //object x1 = ser.Deserialize<X []> (null);
361 //object x2 = ser.Deserialize<X []> ("");
362 //object d = ser.Deserialize<X[]> (x);
366 public void TestDeserializeUnquotedKeys ()
368 JavaScriptSerializer ser = new JavaScriptSerializer ();
369 IDictionary dict = ser.Deserialize <Dictionary <string, object>> ("{itemOne:\"1\",itemTwo:\"2\"}");
371 Assert.AreEqual ("1", dict ["itemOne"], "#A1");
372 Assert.AreEqual ("2", dict ["itemTwo"], "#A2");
374 dict = ser.Deserialize <Dictionary <string, object>> ("{itemOne:1,itemTwo:2}");
375 Assert.AreEqual (1, dict ["itemOne"], "#B1");
376 Assert.AreEqual (2, dict ["itemTwo"], "#B2");
380 public void TestDeserializeUnquotedKeysWithSpaces ()
382 JavaScriptSerializer ser = new JavaScriptSerializer ();
383 IDictionary dict = ser.Deserialize <Dictionary <string, object>> ("{ itemOne :\"1\",itemTwo:\"2\"}");
385 Assert.AreEqual ("1", dict ["itemOne"], "#A1");
386 Assert.AreEqual ("2", dict ["itemTwo"], "#A2");
388 dict = ser.Deserialize <Dictionary <string, object>> ("{ itemOne :1, itemTwo :2}");
389 Assert.AreEqual (1, dict ["itemOne"], "#B1");
390 Assert.AreEqual (2, dict ["itemTwo"], "#B2");
394 public void TestDeserialize () {
395 JavaScriptSerializer ser = new JavaScriptSerializer ();
396 Assert.IsNull (ser.Deserialize<X> (""));
400 string x = ser.Serialize (s);
402 Assert.AreEqual ("{\"z\":8,\"ch\":\"v\",\"ch_null\":null,\"str\":\"vwF59g\",\"b\":253,\"sb\":-48,\"sh\":-32740,\"ush\":65511,\"i\":-234235453,\"ui\":4294733061,\"l\":-9223372036854775780,\"ul\":18446744073709551612,\"f\":NaN,\"f1\":-Infinity,\"f2\":Infinity,\"f3\":-3.40282347E+38,\"f4\":3.40282347E+38,\"d\":NaN,\"d1\":-Infinity,\"d2\":Infinity,\"d3\":-1.7976931348623157E+308,\"d4\":1.7976931348623157E+308,\"de\":-1,\"de1\":0,\"de2\":1,\"de3\":-79228162514264337593543950335,\"de4\":79228162514264337593543950335,\"g\":\"000000ea-0002-0162-0102-030405060708\",\"nb\":null,\"dbn\":null,\"uri\":\"http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d\",\"hash\":{\"mykey\":{\"BB\":10}},\"point\":{\"IsEmpty\":false,\"X\":150,\"Y\":150},\"MyEnum\":[1,10,345],\"MyEnum1\":[1,10,345],\"AA\":5,\"AA1\":[{\"BB\":10},{\"BB\":10}],\"BB\":18446744073709551610,\"YY\":[{\"BB\":10},{\"BB\":10}]}", x, "#A1");
404 X n = ser.Deserialize<X> (x);
405 Assert.AreEqual (s, n, "#A2");
407 //string json = "\\uFF56";
408 //string result = ser.Deserialize<string> (json);
409 //Assert.AreEqual ("\uFF56", result);
411 //object oo = ser.DeserializeObject ("{value:'Purple\\r \\n monkey\\'s:\\tdishwasher'}");
415 public void TestDeserializeNonGenericOverload()
417 JavaScriptSerializer ser = new JavaScriptSerializer();
418 Assert.IsNull(ser.Deserialize("", typeof(X)));
422 string x = ser.Serialize(s);
424 Assert.AreEqual("{\"z\":8,\"ch\":\"v\",\"ch_null\":null,\"str\":\"vwF59g\",\"b\":253,\"sb\":-48,\"sh\":-32740,\"ush\":65511,\"i\":-234235453,\"ui\":4294733061,\"l\":-9223372036854775780,\"ul\":18446744073709551612,\"f\":NaN,\"f1\":-Infinity,\"f2\":Infinity,\"f3\":-3.40282347E+38,\"f4\":3.40282347E+38,\"d\":NaN,\"d1\":-Infinity,\"d2\":Infinity,\"d3\":-1.7976931348623157E+308,\"d4\":1.7976931348623157E+308,\"de\":-1,\"de1\":0,\"de2\":1,\"de3\":-79228162514264337593543950335,\"de4\":79228162514264337593543950335,\"g\":\"000000ea-0002-0162-0102-030405060708\",\"nb\":null,\"dbn\":null,\"uri\":\"http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d\",\"hash\":{\"mykey\":{\"BB\":10}},\"point\":{\"IsEmpty\":false,\"X\":150,\"Y\":150},\"MyEnum\":[1,10,345],\"MyEnum1\":[1,10,345],\"AA\":5,\"AA1\":[{\"BB\":10},{\"BB\":10}],\"BB\":18446744073709551610,\"YY\":[{\"BB\":10},{\"BB\":10}]}", x, "#A1");
426 X n = ser.Deserialize(x, typeof(X)) as X;
427 Assert.AreEqual(s, n, "#A2");
431 public void TestDeserializeTypeResolver ()
434 string expected = "{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+X, System.Web.Extensions_test_net_4_5, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"z\":8,\"ch\":\"v\",\"ch_null\":null,\"str\":\"vwF59g\",\"b\":253,\"sb\":-48,\"sh\":-32740,\"ush\":65511,\"i\":-234235453,\"ui\":4294733061,\"l\":-9223372036854775780,\"ul\":18446744073709551612,\"f\":NaN,\"f1\":-Infinity,\"f2\":Infinity,\"f3\":-3.40282347E+38,\"f4\":3.40282347E+38,\"d\":NaN,\"d1\":-Infinity,\"d2\":Infinity,\"d3\":-1.7976931348623157E+308,\"d4\":1.7976931348623157E+308,\"de\":-1,\"de1\":0,\"de2\":1,\"de3\":-79228162514264337593543950335,\"de4\":79228162514264337593543950335,\"g\":\"000000ea-0002-0162-0102-030405060708\",\"nb\":null,\"dbn\":null,\"uri\":\"http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d\",\"hash\":{\"mykey\":{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_5, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}},\"point\":{\"__type\":\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\"IsEmpty\":false,\"X\":150,\"Y\":150},\"MyEnum\":[1,10,345],\"MyEnum1\":[1,10,345],\"AA\":5,\"AA1\":[{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_5, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10},{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_5, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}],\"BB\":18446744073709551610,\"YY\":[{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_5, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10},{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_5, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}]}";
436 string expected = "{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+X, System.Web.Extensions_test_net_4_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"z\":8,\"ch\":\"v\",\"ch_null\":null,\"str\":\"vwF59g\",\"b\":253,\"sb\":-48,\"sh\":-32740,\"ush\":65511,\"i\":-234235453,\"ui\":4294733061,\"l\":-9223372036854775780,\"ul\":18446744073709551612,\"f\":NaN,\"f1\":-Infinity,\"f2\":Infinity,\"f3\":-3.40282347E+38,\"f4\":3.40282347E+38,\"d\":NaN,\"d1\":-Infinity,\"d2\":Infinity,\"d3\":-1.7976931348623157E+308,\"d4\":1.7976931348623157E+308,\"de\":-1,\"de1\":0,\"de2\":1,\"de3\":-79228162514264337593543950335,\"de4\":79228162514264337593543950335,\"g\":\"000000ea-0002-0162-0102-030405060708\",\"nb\":null,\"dbn\":null,\"uri\":\"http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d\",\"hash\":{\"mykey\":{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}},\"point\":{\"__type\":\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\"IsEmpty\":false,\"X\":150,\"Y\":150},\"MyEnum\":[1,10,345],\"MyEnum1\":[1,10,345],\"AA\":5,\"AA1\":[{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10},{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}],\"BB\":18446744073709551610,\"YY\":[{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10},{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}]}";
438 string expected = "{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+X, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"z\":8,\"ch\":\"v\",\"ch_null\":null,\"str\":\"vwF59g\",\"b\":253,\"sb\":-48,\"sh\":-32740,\"ush\":65511,\"i\":-234235453,\"ui\":4294733061,\"l\":-9223372036854775780,\"ul\":18446744073709551612,\"f\":NaN,\"f1\":-Infinity,\"f2\":Infinity,\"f3\":-3.40282347E+38,\"f4\":3.40282347E+38,\"d\":NaN,\"d1\":-Infinity,\"d2\":Infinity,\"d3\":-1.7976931348623157E+308,\"d4\":1.7976931348623157E+308,\"de\":-1,\"de1\":0,\"de2\":1,\"de3\":-79228162514264337593543950335,\"de4\":79228162514264337593543950335,\"g\":\"000000ea-0002-0162-0102-030405060708\",\"nb\":null,\"dbn\":null,\"uri\":\"http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d\",\"hash\":{\"mykey\":{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}},\"point\":{\"__type\":\"System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\"IsEmpty\":false,\"X\":150,\"Y\":150},\"MyEnum\":[1,10,345],\"MyEnum1\":[1,10,345],\"AA\":5,\"AA1\":[{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10},{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}],\"BB\":18446744073709551610,\"YY\":[{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10},{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}]}";
440 JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver ());
444 string s = ser.Serialize (x);
445 Assert.AreEqual (expected, s, "#A1");
447 X x2 = ser.Deserialize<X> (s);
448 Assert.AreEqual (x, x2, "#A2");
452 public void TestDeserializeBugs () {
453 JavaScriptSerializer ser = new JavaScriptSerializer ();
457 string x = ser.Serialize (s);
458 bug n = ser.Deserialize<bug> (x);
459 Assert.AreEqual (s, n);
461 // Should check correctness with .Net GA:
462 //js = ser.Serialize (Color.Red);
463 //Color ccc = ser.Deserialize<Color> (js);
464 //string xml = @"<root><node attr=""xxx""/></root>";
466 //XmlDocument doc = new XmlDocument ();
468 //string js = ser.Serialize (doc);
469 //DataTable table = new DataTable();
470 //table.Columns.Add ("col1", typeof (int));
471 //table.Columns.Add ("col2", typeof (float));
472 //table.Rows.Add (1, 1f);
473 //table.Rows.Add (234234, 2.4f);
475 //string js = ser.Serialize (table);
478 static void FieldsEqual (object expected, object actual) {
479 Assert.AreEqual (expected.GetType (), actual.GetType ());
480 FieldInfo [] infos = expected.GetType ().GetFields (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
481 foreach (FieldInfo info in infos) {
482 object value1 = info.GetValue (expected);
483 object value2 = info.GetValue (actual);
484 if (value1 is IEnumerable) {
485 IEnumerator yenum = ((IEnumerable) value2).GetEnumerator ();
487 foreach (object x in (IEnumerable) value1) {
488 if (!yenum.MoveNext ())
489 Assert.Fail (info.Name + " index:" + index);
491 if (x is DictionaryEntry) {
492 DictionaryEntry entry = (DictionaryEntry)x;
493 IDictionary dict = (IDictionary) value2;
494 Assert.AreEqual (entry.Value, dict [entry.Key], info.Name + ", key:" + entry.Key);
497 Assert.AreEqual (x, yenum.Current, info.Name + ", index:" + index);
499 Assert.IsFalse (yenum.MoveNext (), info.Name);
502 Assert.AreEqual (value1, value2, info.Name);
508 [ExpectedException (typeof (ArgumentNullException))]
509 public void TestDeserialize1 () {
510 JavaScriptSerializer ser = new JavaScriptSerializer ();
511 ser.Deserialize<string> (null);
515 [ExpectedException (typeof (ArgumentNullException))]
516 public void TestDeserializeNullConverter () {
517 JavaScriptSerializer ser = new JavaScriptSerializer ();
518 ser.RegisterConverters (null);
522 [SetCulture ("en-US")]
523 public void TestDeserializeConverter () {
524 JavaScriptSerializer ser = new JavaScriptSerializer ();
525 List<JavaScriptConverter> list = new List<JavaScriptConverter> ();
526 list.Add (new MyJavaScriptConverter ());
527 list.Add (new CultureInfoConverter ());
528 ser.RegisterConverters (list);
529 string result = ser.Serialize (new X [] { new X (), new X () });
530 Assert.AreEqual ("{\"0\":1,\"1\":2}", result);
531 result = ser.Serialize (Thread.CurrentThread.CurrentCulture);
535 public void TestDeserializeConverter1 () {
536 JavaScriptSerializer serializer = new JavaScriptSerializer ();
538 serializer.RegisterConverters (new JavaScriptConverter [] {new ListItemCollectionConverter()});
540 ListBox ListBox1 = new ListBox ();
541 ListBox1.Items.Add ("a1");
542 ListBox1.Items.Add ("a2");
543 ListBox1.Items.Add ("a3");
545 string x = serializer.Serialize (ListBox1.Items);
546 ListItemCollection recoveredList = serializer.Deserialize<ListItemCollection> (x);
547 Assert.AreEqual (3, recoveredList.Count);
551 public void TestSerialize1 () {
552 JavaScriptSerializer ser = new JavaScriptSerializer ();
553 Assert.AreEqual("null", ser.Serialize(null));
555 string js = ser.Serialize (1234);
556 Assert.AreEqual ("1234", js);
557 Assert.AreEqual (1234, ser.Deserialize<int> (js));
558 js = ser.Serialize (1.1);
559 Assert.AreEqual ("1.1", js);
560 Assert.AreEqual (1.1f, ser.Deserialize<float> (js));
561 char [] chars = "faskjhfasd0981234".ToCharArray ();
562 js = ser.Serialize (chars);
563 char[] actual = ser.Deserialize<char[]> (js);
564 Assert.AreEqual (chars.Length, actual.Length);
565 for (int i = 0; i < chars.Length; i++)
566 Assert.AreEqual (chars[i], actual[i]);
568 string expected = @"""\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\""#$%&\u0027()*+,-./0123456789:;\u003c=\u003e?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~""";
569 string data = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&\u0027()*+,-./0123456789:;\u003c=\u003e?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
571 string serRes = ser.Serialize (data);
572 Assert.AreEqual (expected, serRes);
573 string deserRes = ser.Deserialize<string> (serRes);
574 Assert.AreEqual (data, deserRes);
578 [ExpectedException (typeof (ArgumentNullException))]
579 [Category ("NotDotNet")]
580 public void TestSerialize2 () {
581 JavaScriptSerializer ser = new JavaScriptSerializer ();
582 ser.Serialize ("aaa", (StringBuilder)null);
585 static readonly long InitialJavaScriptDateTicks = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
588 public void TestSerializeDate () {
589 JavaScriptSerializer ser = new JavaScriptSerializer ();
590 DateTime now = new DateTime (633213894056010000L);
592 string actual = ser.Serialize (now);
593 DateTime dateTime = now.ToUniversalTime ();
594 long javaScriptTicks = (dateTime.Ticks - InitialJavaScriptDateTicks) / (long) 10000;
596 object dd = ser.DeserializeObject (@"""\/Datte(" + javaScriptTicks + @")\/""");
597 Assert.AreEqual (@"""\/Date(" + javaScriptTicks + @")\/""", actual);
598 Assert.AreEqual (now.ToUniversalTime(), ser.DeserializeObject (actual));
602 public void TestSerializeEnum () {
603 JavaScriptSerializer ser = new JavaScriptSerializer ();
604 string result = ser.Serialize (MyEnum.BBB);
605 Assert.AreEqual ("1", result);
606 Assert.AreEqual (MyEnum.BBB, ser.Deserialize<MyEnum> (result));
609 class MyJavaScriptConverter : JavaScriptConverter
611 public override object Deserialize (IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) {
612 throw new Exception ("The method or operation is not implemented.");
615 public override IDictionary<string, object> Serialize (object obj, JavaScriptSerializer serializer) {
616 Array a = (Array) obj;
617 Dictionary<string, object> d = new Dictionary<string, object> ();
621 //throw new Exception ("The method or operation is not implemented.");
624 public override IEnumerable<Type> SupportedTypes {
626 yield return typeof (X[]);
631 sealed class CultureInfoConverter : JavaScriptConverter
633 static readonly Type typeofCultureInfo = typeof (CultureInfo);
634 public override IEnumerable<Type> SupportedTypes {
635 get { yield return typeofCultureInfo; }
638 public override object Deserialize (IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) {
639 throw new NotSupportedException ();
642 public override IDictionary<string, object> Serialize (object obj, JavaScriptSerializer serializer) {
643 CultureInfo ci = (CultureInfo)obj;
646 Dictionary<string, object> d = new Dictionary<string, object> ();
647 d.Add ("name", ci.Name);
648 d.Add ("numberFormat", ci.NumberFormat);
649 d.Add ("dateTimeFormat", ci.DateTimeFormat);
654 public class ListItemCollectionConverter : JavaScriptConverter
656 public override IEnumerable<Type> SupportedTypes {
657 //Define the ListItemCollection as a supported type.
658 get { return new ReadOnlyCollection<Type> (new Type [] { typeof (ListItemCollection) }); }
661 public override IDictionary<string, object> Serialize (object obj, JavaScriptSerializer serializer) {
662 ListItemCollection listType = obj as ListItemCollection;
664 if (listType != null) {
665 // Create the representation.
666 Dictionary<string, object> result = new Dictionary<string, object> ();
667 ArrayList itemsList = new ArrayList ();
668 foreach (ListItem item in listType) {
669 //Add each entry to the dictionary.
670 Dictionary<string, object> listDict = new Dictionary<string, object> ();
671 listDict.Add ("Value", item.Value);
672 listDict.Add ("Text", item.Text);
673 itemsList.Add (listDict);
675 result ["List"] = itemsList;
679 return new Dictionary<string, object> ();
682 public override object Deserialize (IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) {
683 if (dictionary == null)
684 throw new ArgumentNullException ("dictionary");
686 if (type == typeof (ListItemCollection)) {
687 // Create the instance to deserialize into.
688 ListItemCollection list = new ListItemCollection ();
690 // Deserialize the ListItemCollection's items.
691 ArrayList itemsList = (ArrayList) dictionary ["List"];
692 for (int i = 0; i < itemsList.Count; i++)
693 list.Add (serializer.ConvertToType<ListItem> (itemsList [i]));
702 public void DeserializeObject () {
703 object o = new JavaScriptSerializer ().DeserializeObject ("{\"Numeric\":0,\"Array\":[true,false,0]}");
704 Assert.IsNotNull (o as Dictionary<string, object>, "type");
705 Dictionary<string, object> dictionary = (Dictionary<string, object>) o;
706 Assert.AreEqual (0, (int) dictionary ["Numeric"], "Numeric");
707 Assert.IsNotNull (dictionary ["Array"] as object [], "Array type");
708 object [] array = (object []) dictionary ["Array"];
709 Assert.AreEqual (true, (bool) array [0], "array [0]");
710 Assert.AreEqual (false, (bool) array [1], "array [1]");
711 Assert.AreEqual (0, (int) array [2], "array [2]");
715 public void DeserializeObject2 ()
717 JavaScriptSerializer ser = new JavaScriptSerializer ();
719 string s = ser.Serialize (y);
720 object y2 = ser.DeserializeObject (s);
721 Assert.AreEqual (typeof (Dictionary<string, object>), y2.GetType (), "DeserializeObject to Dictionary");
725 public void DeserializeObject3 ()
727 JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver());
729 string s = ser.Serialize (y);
730 object y2 = ser.DeserializeObject (s);
731 Assert.AreEqual (typeof (Y), y2.GetType (), "DeserializeObject to Dictionary");
735 public void DeserializeObject4 ()
737 JavaScriptSerializer ser = new JavaScriptSerializer (new CustomResolver());
739 string s = ser.Serialize (y);
740 object y2 = ser.DeserializeObject (s);
741 Assert.AreEqual (typeof (Y), y2.GetType (), "DeserializeObject to Dictionary");
742 Assert.AreEqual (1, CustomResolver.ResolvedIds.Count, "ResolvedIds Count");
743 Assert.AreEqual ("Y", CustomResolver.ResolvedIds [0], "ResolvedIds.Y");
744 Assert.AreEqual (1, CustomResolver.ResolvedTypes.Count, "ResolvedTypes Count");
745 Assert.AreEqual ("Y", CustomResolver.ResolvedTypes [0], "ResolvedTypes.Y");
749 [ExpectedException(typeof(ArgumentNullException))]
750 public void SerializeWithResolverDeserializeWithout ()
752 JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver ());
754 string s = ser.Serialize (y);
755 ser = new JavaScriptSerializer ();
756 object y2 = ser.DeserializeObject (s);
760 public void SerializeWithoutResolverDeserializeWith ()
762 JavaScriptSerializer ser = new JavaScriptSerializer ();
764 string s = ser.Serialize (y);
765 ser = new JavaScriptSerializer (new SimpleTypeResolver ());
766 object y2 = ser.DeserializeObject (s);
767 Assert.AreEqual (typeof (Dictionary<string, object>), y2.GetType (), "DeserializeObject to Dictionary");
773 public string s1 = "s1";
779 public string s2 = "s2";
784 public B b1 = new B ();
785 public B b2 = new D ();
789 public void SerializeDerivedType ()
791 JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver ());
793 string s = ser.Serialize (b);
794 B b2 = ser.Deserialize<B> (s);
795 Assert.AreEqual (typeof (D), b2.GetType (), "Deserialize Derived Type");
799 public void SerializeDerivedType2 ()
801 JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver ());
803 string s = ser.Serialize (b);
804 B b2 = (B)ser.DeserializeObject (s);
805 Assert.AreEqual (typeof (D), b2.GetType (), "Deserialize Derived Type");
809 public void SerializeContainedDerivedType ()
811 JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver ());
813 string s = ser.Serialize (c);
814 C c2 = ser.Deserialize<C> (s);
815 Assert.AreEqual (typeof (C), c2.GetType (), "Deserialize Derived Type");
816 Assert.AreEqual (typeof (D), c2.b2.GetType (), "Deserialize Derived Type");
820 public void SerializeContainedDerivedType2 ()
822 JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver ());
824 string s = ser.Serialize (c);
825 C c2 = (C)ser.DeserializeObject (s);
826 Assert.AreEqual (typeof (C), c2.GetType (), "Deserialize Derived Type");
827 Assert.AreEqual (typeof (D), c2.b2.GetType (), "Deserialize Derived Type");
831 public void SerializeWithTypeConverter ()
833 JavaScriptSerializer ser = new JavaScriptSerializer ();
834 MyUri uri = new MyUri ("http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d", UriKind.RelativeOrAbsolute);
835 string s = ser.Serialize (uri);
836 MyUri uri2 = ser.Deserialize<MyUri> (s);
837 Assert.AreEqual (uri, uri2);
841 public void SerializeWithTypeConverter2 ()
843 JavaScriptSerializer ser = new JavaScriptSerializer ();
844 MyPointContainer pc = new MyPointContainer(new Point(15, 16));
845 string s = ser.Serialize(pc);
846 MyPointContainer pc2 = ser.Deserialize<MyPointContainer>(s);
850 public void MaxJsonLengthDeserializeObject ()
852 JavaScriptSerializer ser = new JavaScriptSerializer ();
853 ser.MaxJsonLength = 16;
854 object o = ser.DeserializeObject ("{s:'1234567890'}");
858 [ExpectedException(typeof(ArgumentException))]
859 public void MaxJsonLengthDeserializeObjectToLong ()
861 JavaScriptSerializer ser = new JavaScriptSerializer ();
862 ser.MaxJsonLength = 15;
863 object o = ser.DeserializeObject ("{s:'1234567890'}");
867 public void MaxJsonLengthSerialize ()
869 JavaScriptSerializer ser = new JavaScriptSerializer ();
870 ser.MaxJsonLength = 9;
872 string s = ser.Serialize (y);
876 [ExpectedException (typeof (InvalidOperationException))]
877 public void MaxJsonLengthSerializeToLong ()
879 JavaScriptSerializer ser = new JavaScriptSerializer ();
880 ser.MaxJsonLength = 8;
882 string s = ser.Serialize (y);
886 public void RecursionLimitDeserialize1 ()
888 JavaScriptSerializer ser = new JavaScriptSerializer ();
889 ser.RecursionLimit = 3;
890 YY yy = ser.Deserialize<YY> ("{\"Y1\":{\"BB\":10},\"Y2\":{\"BB\":10}}");
894 public void RecursionLimitDeserialize2 ()
896 JavaScriptSerializer ser = new JavaScriptSerializer ();
897 ser.RecursionLimit = 2;
898 YY yy = ser.Deserialize<YY> ("{\"Y1\":{},\"Y2\":{}}");
902 public void RecursionLimitDeserialize3 ()
904 JavaScriptSerializer ser = new JavaScriptSerializer ();
905 ser.RecursionLimit = 1;
906 object o = ser.DeserializeObject ("\"xxx\"");
910 [ExpectedException(typeof(ArgumentException))]
911 public void RecursionLimitDeserializeToDeep ()
913 JavaScriptSerializer ser = new JavaScriptSerializer ();
914 ser.RecursionLimit = 2;
915 YY yy = ser.Deserialize<YY> ("{\"Y1\":{\"BB\":10},\"Y2\":{\"BB\":10}}");
919 public void RecursionLimitSerialize ()
921 JavaScriptSerializer ser = new JavaScriptSerializer ();
922 ser.RecursionLimit = 3;
924 string s = ser.Serialize (yy);
928 [ExpectedException(typeof(ArgumentException))]
929 public void RecursionLimitSerializeToDeep ()
931 JavaScriptSerializer ser = new JavaScriptSerializer ();
932 ser.RecursionLimit = 2;
934 string s = ser.Serialize (yy);
938 public void RecursionLimitSerialize2 ()
940 JavaScriptSerializer ser = new JavaScriptSerializer ();
941 ser.RecursionLimit = 2;
943 StringBuilder b = new StringBuilder ();
944 bool caughtException = false;
946 ser.Serialize (yy, b);
949 caughtException = true;
951 Assert.IsTrue (caughtException, "RecursionLimitSerialize2 Expected an exception!");
952 Assert.AreEqual ("{\"Y1\":{\"BB\":", b.ToString (), "RecursionLimitSerialize2");
956 public void SimpleTypeResolver ()
958 JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver ());
960 string s = ser.Serialize (yy);
961 string expected = String.Format("\"__type\":\"{0}\"", yy.GetType().AssemblyQualifiedName);
963 Assert.IsTrue (s.Contains (expected), "YY: expected {0} to contain {1}", s, expected);
965 expected = String.Format ("\"__type\":\"{0}\"", yy.Y1.GetType ().AssemblyQualifiedName);
966 Assert.IsTrue (s.Contains (expected), "Y: expected {0} to contain {1}", s, expected);
969 public class CustomResolver : JavaScriptTypeResolver
971 public CustomResolver ()
976 public override Type ResolveType (string id)
978 ResolvedIds.Add (id);
994 return typeof (long);
997 return typeof (string);
1000 return typeof(Point);
1005 public override string ResolveTypeId (Type type)
1008 throw new ArgumentNullException ("type");
1011 ResolvedTypes.Add (type.Name);
1013 if (type == typeof (YY))
1016 if (type == typeof (Y))
1019 if (type == typeof (X))
1022 if (type == typeof (int))
1025 if (type == typeof (long))
1028 if (type == typeof (string))
1031 if (type == typeof(Point))
1037 public static List<string> ResolvedTypes {
1039 if (resolvedTypes == null) {
1040 resolvedTypes = new List<string> ();
1042 return resolvedTypes;
1046 public static List<string> ResolvedIds {
1048 if (resolvedIds == null) {
1049 resolvedIds = new List<string> ();
1055 public static void Reset ()
1058 resolvedTypes = null;
1061 private static List<string> resolvedTypes;
1062 private static List<string> resolvedIds;
1066 [NUnit.Framework.Category ("NotWorking")]
1067 public void CustomTypeResolver ()
1069 JavaScriptSerializer ser = new JavaScriptSerializer (new CustomResolver ());
1073 string s = ser.Serialize (x);
1075 CustomResolver.Reset ();
1076 X x1 = (X) ser.DeserializeObject (s);
1077 Assert.IsTrue (x.Equals (x1), "x != x1");
1079 CustomResolver.Reset ();
1080 X x2 = ser.Deserialize<X> (s);
1081 Assert.IsTrue (x.Equals (x2), "x != x2");
1085 public void InfinityAndNaN ()
1087 JavaScriptSerializer ser = new JavaScriptSerializer ();
1089 double nan = Double.NaN;
1090 string s = ser.Serialize (nan);
1091 Assert.AreEqual (s, "NaN", "#A1");
1092 nan = (double)ser.DeserializeObject (s);
1093 Assert.AreEqual (Double.NaN, nan, "#A2");
1094 nan = (double)ser.Deserialize <double> (s);
1095 Assert.AreEqual (Double.NaN, nan, "#A3");
1097 double infinity = Double.PositiveInfinity;
1098 s = ser.Serialize (infinity);
1099 Assert.AreEqual (s, "Infinity", "#B1");
1100 infinity = (double)ser.DeserializeObject (s);
1101 Assert.AreEqual (Double.PositiveInfinity, infinity, "#B2");
1102 infinity = ser.Deserialize <double> (s);
1103 Assert.AreEqual (Double.PositiveInfinity, infinity, "#B3");
1105 infinity = Double.NegativeInfinity;
1106 s = ser.Serialize (infinity);
1107 Assert.AreEqual (s, "-Infinity", "#C1");
1108 infinity = (double)ser.DeserializeObject (s);
1109 Assert.AreEqual (Double.NegativeInfinity, infinity, "#C2");
1110 infinity = ser.Deserialize <double> (s);
1111 Assert.AreEqual (Double.NegativeInfinity, infinity, "#C3");
1113 var dict = new Dictionary <string, object> ();
1114 dict.Add ("A", Double.NaN);
1115 dict.Add ("B", Double.PositiveInfinity);
1116 dict.Add ("C", Double.NegativeInfinity);
1117 s = ser.Serialize (dict);
1118 Assert.AreEqual ("{\"A\":NaN,\"B\":Infinity,\"C\":-Infinity}", s, "#D1");
1120 dict = (Dictionary <string, object>)ser.DeserializeObject (s);
1121 Assert.AreEqual (Double.NaN, dict ["A"], "#D2");
1122 Assert.AreEqual (Double.PositiveInfinity, dict ["B"], "#D3");
1123 Assert.AreEqual (Double.NegativeInfinity, dict ["C"], "#D4");
1125 dict = (Dictionary <string, object>)ser.Deserialize <Dictionary <string, object>> (s);
1126 Assert.AreEqual (Double.NaN, dict ["A"], "#D5");
1127 Assert.AreEqual (Double.PositiveInfinity, dict ["B"], "#D6");
1128 Assert.AreEqual (Double.NegativeInfinity, dict ["C"], "#D7");
1130 var arr = new ArrayList () {
1132 Double.PositiveInfinity,
1133 Double.NegativeInfinity};
1134 s = ser.Serialize (arr);
1135 Assert.AreEqual ("[NaN,Infinity,-Infinity]", s, "#E1");
1137 object[] arr2 = (object[])ser.DeserializeObject (s);
1138 Assert.AreEqual (3, arr2.Length, "#E2");
1139 Assert.AreEqual (Double.NaN, arr2 [0], "#E3");
1140 Assert.AreEqual (Double.PositiveInfinity, arr2 [1], "#E4");
1141 Assert.AreEqual (Double.NegativeInfinity, arr2 [2], "#E5");
1143 arr = ser.Deserialize <ArrayList> (s);
1144 Assert.AreEqual (3, arr.Count, "#E6");
1145 Assert.AreEqual (Double.NaN, arr [0], "#E7");
1146 Assert.AreEqual (Double.PositiveInfinity, arr [1], "#E8");
1147 Assert.AreEqual (Double.NegativeInfinity, arr [2], "#E9");
1151 public void StandalonePrimitives ()
1153 JavaScriptSerializer ser = new JavaScriptSerializer ();
1158 o = ser.DeserializeObject ("1");
1159 Assert.AreEqual (typeof (global::System.Int32), o.GetType (), "#A1");
1161 Assert.AreEqual (1, i, "#A2");
1162 o =ser.DeserializeObject ("-1");
1163 Assert.AreEqual (typeof (global::System.Int32), o.GetType (), "#A3");
1165 Assert.AreEqual (-1, i, "#A4");
1167 o = ser.DeserializeObject ("2147483649");
1168 Assert.AreEqual (typeof (global::System.Int64), o.GetType (), "#B1");
1170 Assert.AreEqual (2147483649, l, "#B2");
1171 o = ser.DeserializeObject ("-2147483649");
1172 Assert.AreEqual (typeof (global::System.Int64), o.GetType (), "#B3");
1174 Assert.AreEqual (-2147483649, l, "#B4");
1176 o = ser.DeserializeObject ("9223372036854775808");
1177 Assert.AreEqual (typeof (global::System.Decimal), o.GetType (), "#C1");
1178 decimal d = (decimal)o;
1179 Assert.AreEqual (9223372036854775808m, d, "#C2");
1180 o = ser.DeserializeObject ("-9223372036854775809");
1181 Assert.AreEqual (typeof (global::System.Decimal), o.GetType (), "#C3");
1183 Assert.AreEqual (-9223372036854775809m, d, "#C4");
1185 o = ser.DeserializeObject ("79228162514264337593543950336");
1186 Assert.AreEqual (typeof (global::System.Double), o.GetType (), "#D1");
1187 double db = (double)o;
1188 Assert.AreEqual (79228162514264337593543950336.0, db, "#D2");
1189 o = ser.DeserializeObject ("-79228162514264337593543950336");
1190 Assert.AreEqual (typeof (global::System.Double), o.GetType (), "#D3");
1192 Assert.AreEqual (-79228162514264337593543950336.0, db, "#D4");
1194 o = ser.DeserializeObject ("\"test string\"");
1195 Assert.AreEqual (typeof (global::System.String), o.GetType (), "#E1");
1196 string s = (string)o;
1197 Assert.AreEqual ("test string", s, "#E2");
1199 o = ser.DeserializeObject ("true");
1200 Assert.AreEqual (typeof (global::System.Boolean), o.GetType (), "#F1");
1202 Assert.AreEqual (true, b, "#F2");
1204 o = ser.DeserializeObject ("false");
1205 Assert.AreEqual (typeof (global::System.Boolean), o.GetType (), "#F3");
1207 Assert.AreEqual (false, b, "#F4");
1209 o = ser.DeserializeObject ("-1.7976931348623157E+308");
1210 Assert.AreEqual (typeof (global::System.Double), o.GetType (), "#G1");
1212 Assert.AreEqual (Double.MinValue, db, "#G2");
1214 o = ser.DeserializeObject ("1.7976931348623157E+308");
1215 Assert.AreEqual (typeof (global::System.Double), o.GetType (), "#G3");
1217 Assert.AreEqual (Double.MaxValue, db, "#G4");
1220 class SomeDict : IDictionary<string, object>
1222 void IDictionary<string, object>.Add (string key, object value) {
1223 throw new NotSupportedException ();
1226 bool IDictionary<string, object>.ContainsKey (string key) {
1227 throw new NotSupportedException ();
1230 ICollection<string> IDictionary<string, object>.Keys {
1231 get { throw new NotSupportedException (); }
1234 bool IDictionary<string, object>.Remove (string key) {
1235 throw new NotSupportedException ();
1238 bool IDictionary<string, object>.TryGetValue (string key, out object value) {
1239 throw new NotSupportedException ();
1242 ICollection<object> IDictionary<string, object>.Values {
1243 get { throw new NotSupportedException (); }
1246 object IDictionary<string, object>.this [string key] {
1247 get { throw new NotSupportedException (); }
1248 set { throw new NotSupportedException (); }
1251 void ICollection<KeyValuePair<string, object>>.Add (KeyValuePair<string, object> item) {
1252 throw new NotSupportedException ();
1255 void ICollection<KeyValuePair<string, object>>.Clear () {
1256 throw new NotSupportedException ();
1259 bool ICollection<KeyValuePair<string, object>>.Contains (KeyValuePair<string, object> item) {
1260 throw new NotSupportedException ();
1263 void ICollection<KeyValuePair<string, object>>.CopyTo (KeyValuePair<string, object> [] array, int arrayIndex) {
1264 throw new NotSupportedException ();
1267 int ICollection<KeyValuePair<string, object>>.Count {
1268 get { throw new NotSupportedException (); }
1271 bool ICollection<KeyValuePair<string, object>>.IsReadOnly {
1272 get { throw new NotSupportedException (); }
1275 bool ICollection<KeyValuePair<string, object>>.Remove (KeyValuePair<string, object> item) {
1276 throw new NotSupportedException ();
1279 IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator () {
1280 return GetEnumerator ();
1283 IEnumerator IEnumerable.GetEnumerator () {
1284 return ((IEnumerable<KeyValuePair<string, object>>) this).GetEnumerator ();
1287 protected IEnumerator<KeyValuePair<string, object>> GetEnumerator () {
1288 yield return new KeyValuePair<string, object> ("hello", "world");
1292 [Test] //bug #424704
1293 public void NonGenericClassImplementingClosedGenericIDictionary ()
1295 JavaScriptSerializer ser = new JavaScriptSerializer ();
1297 SomeDict dictIn = new SomeDict ();
1299 string s = ser.Serialize (dictIn);
1301 Dictionary<string, object> dictOut = ser.Deserialize<Dictionary<string, object>> (s);
1302 Assert.AreEqual (dictOut.Count, 1, "#1");
1303 Assert.AreEqual (dictOut["hello"], "world", "#2");
1307 public void ConvertToIDictionary ()
1309 JavaScriptSerializer jss = new JavaScriptSerializer ();
1310 string json = "{\"node\":{\"Text\":\"Root Node\",\"Value\":null,\"ExpandMode\":3,\"NavigateUrl\":null,\"PostBack\":true,\"DisabledCssClass\":null,\"SelectedCssClass\":null,\"HoveredCssClass\":null,\"ImageUrl\":null,\"HoveredImageUrl\":null,\"DisabledImageUrl\":null,\"ExpandedImageUrl\":null,\"ContextMenuID\":\"\"},\"context\":{\"NumberOfNodes\":1000}}";
1311 object input = jss.Deserialize<IDictionary>(json);
1312 IDictionary o = jss.ConvertToType<IDictionary>(input);
1314 Assert.IsTrue (o != null, "#A1");
1315 Assert.AreEqual (typeof (Dictionary <string, object>), o.GetType (), "#A2");
1319 public void ConvertToGenericIDictionary ()
1321 JavaScriptSerializer jss = new JavaScriptSerializer ();
1322 string json = "{\"node\":{\"Text\":\"Root Node\",\"Value\":null,\"ExpandMode\":3,\"NavigateUrl\":null,\"PostBack\":true,\"DisabledCssClass\":null,\"SelectedCssClass\":null,\"HoveredCssClass\":null,\"ImageUrl\":null,\"HoveredImageUrl\":null,\"DisabledImageUrl\":null,\"ExpandedImageUrl\":null,\"ContextMenuID\":\"\"},\"context\":{\"NumberOfNodes\":1000}}";
1324 object input = jss.Deserialize<IDictionary>(json);
1326 IDictionary <string, object> o = jss.ConvertToType<IDictionary <string, object>>(input);
1327 Assert.IsTrue (o != null, "#A1");
1328 Assert.AreEqual (typeof (Dictionary <string, object>), o.GetType (), "#A2");
1330 IDictionary <object, object> o1 = jss.ConvertToType<IDictionary <object, object>>(input);
1331 Assert.IsTrue (o1 != null, "#B1");
1332 Assert.AreEqual (typeof (Dictionary <object, object>), o1.GetType (), "#B2");
1336 [ExpectedException (typeof (InvalidOperationException))]
1337 public void ConvertToGenericIDictionary_InvalidDefinition ()
1339 JavaScriptSerializer jss = new JavaScriptSerializer ();
1340 string json = "{\"node\":{\"Text\":\"Root Node\",\"Value\":null,\"ExpandMode\":3,\"NavigateUrl\":null,\"PostBack\":true,\"DisabledCssClass\":null,\"SelectedCssClass\":null,\"HoveredCssClass\":null,\"ImageUrl\":null,\"HoveredImageUrl\":null,\"DisabledImageUrl\":null,\"ExpandedImageUrl\":null,\"ContextMenuID\":\"\"},\"context\":{\"NumberOfNodes\":1000}}";
1342 object input = jss.Deserialize<IDictionary>(json);
1343 IDictionary <int, object> o = jss.ConvertToType<IDictionary <int, object>>(input);
1346 [Test (Description="Bug #655474")]
1347 public void TestRelativeUri()
1349 JavaScriptSerializer ser = new JavaScriptSerializer();
1350 Uri testUri = new Uri("/lala/123", UriKind.Relative);
1351 StringBuilder sb = new StringBuilder();
1353 ser.Serialize(testUri, sb);
1354 Assert.AreEqual ("\"/lala/123\"", sb.ToString ());
1358 public void DeserializeDictionaryOfArrayList ()
1360 var ser = new JavaScriptSerializer ();
1361 string test1 = "{\"key\":{\"subkey\":\"subval\"}}";
1362 string test2 = "{\"key\":[{\"subkey\":\"subval\"}]}";
1364 var ret1 = ser.Deserialize<Dictionary<string, object>>(test1);
1365 Assert.AreEqual (typeof (Dictionary<string, object>), ret1.GetType (), "#1.1");
1366 var ret1v = ret1 ["key"];
1367 Assert.AreEqual (typeof (Dictionary<string, object>), ret1v.GetType (), "#1.2");
1368 var ret1vd = (IDictionary<string,object>) ret1v;
1369 Assert.AreEqual ("subval", ret1vd ["subkey"], "#1.3");
1371 var ret2 = ser.Deserialize<Dictionary<string, object>>(test2);
1372 Assert.AreEqual (typeof (Dictionary<string, object>), ret2.GetType (), "#2.1");
1373 var ret2v = ret2 ["key"];
1374 Assert.AreEqual (typeof (ArrayList), ret2v.GetType (), "#2.2");
1375 var ret2va = (ArrayList) ret2v;
1376 Assert.AreEqual (typeof (Dictionary<string, object>), ret2va [0].GetType (), "#2.3");
1377 var ret2vad = (IDictionary<string,object>) ret2va [0];
1378 Assert.AreEqual ("subval", ret2vad ["subkey"], "#2.4");
1381 class ClassWithNullableEnum
1383 public MyEnum? Value { get; set; }
1387 public void DeserializeNullableEnum ()
1389 var jsonValues = new Dictionary<string, MyEnum?> {
1390 { "{\"Value\":0}", MyEnum.AAA},
1391 { "{\"Value\":\"0\"}", MyEnum.AAA},
1392 { "{\"Value\":null}", null}
1395 var ser = new JavaScriptSerializer ();
1397 foreach (var kv in jsonValues)
1399 var obj = ser.Deserialize<ClassWithNullableEnum> (kv.Key);
1400 Assert.AreEqual (kv.Value, obj.Value);
1405 public void DeserializeStringWithNewline ()
1407 JavaScriptSerializer serializer = new JavaScriptSerializer ();
1408 string json_with_newline = @"
1412 <div id=\""calendar\""><div>
1417 serializer.DeserializeObject (json_with_newline);