2
// Copyright (c) 2007 James Newton-King
4
// Permission is hereby granted, free of charge, to any person
5
// obtaining a copy of this software and associated documentation
6
// files (the "Software"), to deal in the Software without
7
// restriction, including without limitation the rights to use,
8
// copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the
10
// Software is furnished to do so, subject to the following
13
// The above copyright notice and this permission notice shall be
14
// included in all copies or substantial portions of the Software.
16
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
// OTHER DEALINGS IN THE SOFTWARE.
27
#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
30
using Newtonsoft.Json.Tests.Linq;
32
using global::System.Collections;
33
using global::System.Collections.Generic;
34
using global::System.Globalization;
35
using global::System.Runtime.Serialization.Formatters;
36
using global::Newtonsoft.Json.Linq;
37
using global::Newtonsoft.Json.Serialization;
38
using global::Newtonsoft.Json.Tests.TestObjects;
40
using global::NUnit.Framework;
42
using global::Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
43
using TestFixture = global::Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
44
using Test = global::Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
46
using global::Newtonsoft.Json.Utilities;
47
using global::System.Net;
48
using global::System.Runtime.Serialization;
49
using global::System.IO;
51
namespace Newtonsoft.Json.Tests.Serialization
54
public class TypeNameHandlingTests : TestFixtureBase
58
public IList<EmployeeReference> Array { get; set; }
59
public IDictionary<string, EmployeeReference> Dictionary { get; set; }
63
public void SerializeWrapper()
65
Wrapper wrapper = new Wrapper();
66
wrapper.Array = new List<EmployeeReference>
68
new EmployeeReference()
70
wrapper.Dictionary = new Dictionary<string, EmployeeReference>
72
{"First", new EmployeeReference()}
75
string json = JsonConvert.SerializeObject(wrapper, Formatting.Indented, new JsonSerializerSettings
77
TypeNameHandling = TypeNameHandling.Auto
97
Wrapper w2 = JsonConvert.DeserializeObject<Wrapper>(json);
98
CustomAssert.IsInstanceOfType(typeof (List<EmployeeReference>), w2.Array);
99
CustomAssert.IsInstanceOfType(typeof (Dictionary<string, EmployeeReference>), w2.Dictionary);
103
public void WriteTypeNameForObjects()
105
string employeeRef = ReflectionUtils.GetTypeName(typeof (EmployeeReference), FormatterAssemblyStyle.Simple);
107
EmployeeReference employee = new EmployeeReference();
109
string json = JsonConvert.SerializeObject(employee, Formatting.Indented, new JsonSerializerSettings
111
TypeNameHandling = TypeNameHandling.Objects
116
""$type"": """ + employeeRef + @""",
123
public void DeserializeTypeName()
125
string employeeRef = ReflectionUtils.GetTypeName(typeof (EmployeeReference), FormatterAssemblyStyle.Simple);
129
""$type"": """ + employeeRef + @""",
134
object employee = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
136
TypeNameHandling = TypeNameHandling.Objects
139
CustomAssert.IsInstanceOfType(typeof (EmployeeReference), employee);
140
Assert.AreEqual("Name!", ((EmployeeReference) employee).Name);
143
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
145
public void DeserializeTypeNameFromGacAssembly()
147
string cookieRef = ReflectionUtils.GetTypeName(typeof (Cookie), FormatterAssemblyStyle.Simple);
151
""$type"": """ + cookieRef + @"""
154
object cookie = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
156
TypeNameHandling = TypeNameHandling.Objects
159
CustomAssert.IsInstanceOfType(typeof (Cookie), cookie);
164
public void SerializeGenericObjectListWithTypeName()
166
string employeeRef = typeof (EmployeeReference).AssemblyQualifiedName;
167
string personRef = typeof (Person).AssemblyQualifiedName;
169
List<object> values = new List<object>
171
new EmployeeReference
174
Manager = new EmployeeReference {Name = "Frank"}
178
Department = "Department",
179
BirthDate = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc),
180
LastModified = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc)
186
string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
188
TypeNameHandling = TypeNameHandling.Objects,
189
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
195
""$type"": """ + employeeRef + @""",
199
""$type"": """ + employeeRef + @""",
205
""$type"": """ + personRef + @""",
207
""BirthDate"": ""2000-12-30T00:00:00Z"",
208
""LastModified"": ""2000-12-30T00:00:00Z""
216
public void DeserializeGenericObjectListWithTypeName()
218
string employeeRef = typeof (EmployeeReference).AssemblyQualifiedName;
219
string personRef = typeof (Person).AssemblyQualifiedName;
224
""$type"": """ + employeeRef + @""",
228
""$type"": """ + employeeRef + @""",
234
""$type"": """ + personRef + @""",
236
""BirthDate"": ""\/Date(978134400000)\/"",
237
""LastModified"": ""\/Date(978134400000)\/""
243
List<object> values = (List<object>) JsonConvert.DeserializeObject(json, typeof (List<object>), new JsonSerializerSettings
245
TypeNameHandling = TypeNameHandling.Objects,
246
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
249
Assert.AreEqual(4, values.Count);
251
EmployeeReference e = (EmployeeReference) values[0];
252
Person p = (Person) values[1];
254
Assert.AreEqual("Bob", e.Name);
255
Assert.AreEqual("Frank", e.Manager.Name);
257
Assert.AreEqual(null, p.Name);
258
Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.BirthDate);
259
Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.LastModified);
261
Assert.AreEqual("String!", values[2]);
262
Assert.AreEqual((long) int.MinValue, values[3]);
266
public void DeserializeWithBadTypeName()
268
string employeeRef = typeof (EmployeeReference).AssemblyQualifiedName;
269
string personRef = typeof (Person).AssemblyQualifiedName;
273
""$type"": """ + employeeRef + @""",
280
JsonConvert.DeserializeObject(json, typeof (Person), new JsonSerializerSettings
282
TypeNameHandling = TypeNameHandling.Objects,
283
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
286
catch (JsonSerializationException ex)
288
Assert.IsTrue(ex.Message.StartsWith(@"Type specified in JSON '" + employeeRef + @"' is not compatible with '" + personRef + @"'."));
293
public void DeserializeTypeNameWithNoTypeNameHandling()
295
string employeeRef = typeof (EmployeeReference).AssemblyQualifiedName;
299
""$type"": """ + employeeRef + @""",
304
JObject o = (JObject) JsonConvert.DeserializeObject(json);
313
public void DeserializeTypeNameOnly()
317
""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee"",
322
ExceptionAssert.Throws<JsonSerializationException>(
323
"Type specified in JSON 'Newtonsoft.Json.Tests.TestObjects.Employee' was not resolved. Path '$type', line 3, position 56.",
326
JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
328
TypeNameHandling = TypeNameHandling.Objects
333
public interface ICorrelatedMessage
335
string CorrelationId { get; set; }
338
public class SendHttpRequest : ICorrelatedMessage
340
public SendHttpRequest()
342
RequestEncoding = "UTF-8";
346
public string Method { get; set; }
347
public Dictionary<string, string> Headers { get; set; }
348
public string Url { get; set; }
349
public Dictionary<string, string> RequestData;
350
public string RequestBodyText { get; set; }
351
public string User { get; set; }
352
public string Passwd { get; set; }
353
public string RequestEncoding { get; set; }
354
public string CorrelationId { get; set; }
358
public void DeserializeGenericTypeName()
360
string typeName = typeof (SendHttpRequest).AssemblyQualifiedName;
363
""$type"": """ + typeName + @""",
365
""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"",
366
""Id"": ""siedemnaÅcie"",
370
""Url"": ""http://www.onet.pl"",
371
""RequestEncoding"": ""UTF-8"",
372
""CorrelationId"": ""xyz""
375
ICorrelatedMessage message = JsonConvert.DeserializeObject<ICorrelatedMessage>(json, new JsonSerializerSettings
377
TypeNameHandling = TypeNameHandling.Objects,
378
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
381
CustomAssert.IsInstanceOfType(typeof (SendHttpRequest), message);
383
SendHttpRequest request = (SendHttpRequest) message;
384
Assert.AreEqual("xyz", request.CorrelationId);
385
Assert.AreEqual(2, request.RequestData.Count);
386
Assert.AreEqual("siedemnaÅcie", request.RequestData["Id"]);
390
public void SerializeObjectWithMultipleGenericLists()
392
string containerTypeName = typeof (Container).AssemblyQualifiedName;
393
string productListTypeName = typeof (List<Product>).AssemblyQualifiedName;
395
Container container = new Container
397
In = new List<Product>(),
398
Out = new List<Product>()
401
string json = JsonConvert.SerializeObject(container, Formatting.Indented,
402
new JsonSerializerSettings
404
NullValueHandling = NullValueHandling.Ignore,
405
TypeNameHandling = TypeNameHandling.All,
406
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
410
""$type"": """ + containerTypeName + @""",
412
""$type"": """ + productListTypeName + @""",
416
""$type"": """ + productListTypeName + @""",
422
public class TypeNameProperty
424
public string Name { get; set; }
426
[JsonProperty(TypeNameHandling = TypeNameHandling.All)]
427
public object Value { get; set; }
431
public void WriteObjectTypeNameForProperty()
433
string typeNamePropertyRef = ReflectionUtils.GetTypeName(typeof (TypeNameProperty), FormatterAssemblyStyle.Simple);
435
TypeNameProperty typeNameProperty = new TypeNameProperty
438
Value = new TypeNameProperty
444
string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented);
449
""$type"": """ + typeNamePropertyRef + @""",
450
""Name"": ""Nested!"",
455
TypeNameProperty deserialized = JsonConvert.DeserializeObject<TypeNameProperty>(json);
456
Assert.AreEqual("Name!", deserialized.Name);
457
CustomAssert.IsInstanceOfType(typeof (TypeNameProperty), deserialized.Value);
459
TypeNameProperty nested = (TypeNameProperty) deserialized.Value;
460
Assert.AreEqual("Nested!", nested.Name);
461
Assert.AreEqual(null, nested.Value);
465
public void WriteListTypeNameForProperty()
467
string listRef = ReflectionUtils.GetTypeName(typeof (List<int>), FormatterAssemblyStyle.Simple);
469
TypeNameProperty typeNameProperty = new TypeNameProperty
472
Value = new List<int> {1, 2, 3, 4, 5}
475
string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented);
480
""$type"": """ + listRef + @""",
491
TypeNameProperty deserialized = JsonConvert.DeserializeObject<TypeNameProperty>(json);
492
Assert.AreEqual("Name!", deserialized.Name);
493
CustomAssert.IsInstanceOfType(typeof (List<int>), deserialized.Value);
495
List<int> nested = (List<int>) deserialized.Value;
496
Assert.AreEqual(5, nested.Count);
497
Assert.AreEqual(1, nested[0]);
498
Assert.AreEqual(2, nested[1]);
499
Assert.AreEqual(3, nested[2]);
500
Assert.AreEqual(4, nested[3]);
501
Assert.AreEqual(5, nested[4]);
505
public void DeserializeUsingCustomBinder()
509
""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee"",
513
object p = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
515
TypeNameHandling = TypeNameHandling.Objects,
516
Binder = new CustomSerializationBinder()
519
CustomAssert.IsInstanceOfType(typeof (Person), p);
521
Person person = (Person) p;
523
Assert.AreEqual("Name!", person.Name);
526
public class CustomSerializationBinder : SerializationBinder
528
public override Type BindToType(string assemblyName, string typeName)
530
return typeof (Person);
534
#if !(NET20 || NET35)
536
public void SerializeUsingCustomBinder()
538
TypeNameSerializationBinder binder = new TypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests");
540
IList<object> values = new List<object>
544
Name = "Caroline Customer"
548
ProductName = "Elbow Grease",
554
string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
556
TypeNameHandling = TypeNameHandling.Auto,
562
// "$type": "Customer",
563
// "Name": "Caroline Customer"
566
// "$type": "Purchase",
567
// "ProductName": "Elbow Grease",
576
""$type"": ""Customer"",
577
""Name"": ""Caroline Customer""
580
""$type"": ""Purchase"",
581
""ProductName"": ""Elbow Grease"",
587
IList<object> newValues = JsonConvert.DeserializeObject<IList<object>>(json, new JsonSerializerSettings
589
TypeNameHandling = TypeNameHandling.Auto,
590
Binder = new TypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests")
593
CustomAssert.IsInstanceOfType(typeof (Customer), newValues[0]);
594
Customer customer = (Customer) newValues[0];
595
Assert.AreEqual("Caroline Customer", customer.Name);
597
CustomAssert.IsInstanceOfType(typeof (Purchase), newValues[1]);
598
Purchase purchase = (Purchase) newValues[1];
599
Assert.AreEqual("Elbow Grease", purchase.ProductName);
602
public class TypeNameSerializationBinder : SerializationBinder
604
public string TypeFormat { get; private set; }
606
public TypeNameSerializationBinder(string typeFormat)
608
TypeFormat = typeFormat;
611
public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
614
typeName = serializedType.Name;
617
public override Type BindToType(string assemblyName, string typeName)
619
string resolvedTypeName = string.Format(TypeFormat, typeName);
621
return Type.GetType(resolvedTypeName, true);
627
public void CollectionWithAbstractItems()
629
HolderClass testObject = new HolderClass();
630
testObject.TestMember = new ContentSubClass("First One");
631
testObject.AnotherTestMember = new Dictionary<int, IList<ContentBaseClass>>();
632
testObject.AnotherTestMember.Add(1, new List<ContentBaseClass>());
633
testObject.AnotherTestMember[1].Add(new ContentSubClass("Second One"));
634
testObject.AThirdTestMember = new ContentSubClass("Third One");
636
JsonSerializer serializingTester = new JsonSerializer();
637
serializingTester.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
639
StringWriter sw = new StringWriter();
640
using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
642
jsonWriter.Formatting = Formatting.Indented;
643
serializingTester.TypeNameHandling = TypeNameHandling.Auto;
644
serializingTester.Serialize(jsonWriter, testObject);
647
string json = sw.ToString();
649
string contentSubClassRef = ReflectionUtils.GetTypeName(typeof (ContentSubClass), FormatterAssemblyStyle.Simple);
650
string dictionaryRef = ReflectionUtils.GetTypeName(typeof (Dictionary<int, IList<ContentBaseClass>>), FormatterAssemblyStyle.Simple);
651
string listRef = ReflectionUtils.GetTypeName(typeof (List<ContentBaseClass>), FormatterAssemblyStyle.Simple);
653
string expected = @"{
655
""$type"": """ + contentSubClassRef + @""",
656
""SomeString"": ""First One""
658
""AnotherTestMember"": {
659
""$type"": """ + dictionaryRef + @""",
662
""$type"": """ + contentSubClassRef + @""",
663
""SomeString"": ""Second One""
667
""AThirdTestMember"": {
668
""$type"": """ + contentSubClassRef + @""",
669
""SomeString"": ""Third One""
673
Assert.AreEqual(expected, json);
675
StringReader sr = new StringReader(json);
677
JsonSerializer deserializingTester = new JsonSerializer();
679
HolderClass anotherTestObject;
681
using (JsonTextReader jsonReader = new JsonTextReader(sr))
683
deserializingTester.TypeNameHandling = TypeNameHandling.Auto;
685
anotherTestObject = deserializingTester.Deserialize<HolderClass>(jsonReader);
688
Assert.IsNotNull(anotherTestObject);
689
CustomAssert.IsInstanceOfType(typeof (ContentSubClass), anotherTestObject.TestMember);
690
CustomAssert.IsInstanceOfType(typeof (Dictionary<int, IList<ContentBaseClass>>), anotherTestObject.AnotherTestMember);
691
Assert.AreEqual(1, anotherTestObject.AnotherTestMember.Count);
693
IList<ContentBaseClass> list = anotherTestObject.AnotherTestMember[1];
695
CustomAssert.IsInstanceOfType(typeof (List<ContentBaseClass>), list);
696
Assert.AreEqual(1, list.Count);
697
CustomAssert.IsInstanceOfType(typeof (ContentSubClass), list[0]);
701
public void WriteObjectTypeNameForPropertyDemo()
703
Message message = new Message();
704
message.Address = "http://www.google.com";
705
message.Body = new SearchDetails
711
string json = JsonConvert.SerializeObject(message, Formatting.Indented);
713
// "Address": "http://www.google.com",
715
// "$type": "Newtonsoft.Json.Tests.Serialization.SearchDetails, Newtonsoft.Json.Tests",
716
// "Query": "Json.NET",
717
// "Language": "en-us"
721
Message deserialized = JsonConvert.DeserializeObject<Message>(json);
723
SearchDetails searchDetails = (SearchDetails) deserialized.Body;
727
public class UrlStatus
729
public int Status { get; set; }
730
public string Url { get; set; }
735
public void GenericDictionaryObject()
737
Dictionary<string, object> collection = new Dictionary<string, object>()
739
{"First", new UrlStatus {Status = 404, Url = @"http://www.bing.com"}},
740
{"Second", new UrlStatus {Status = 400, Url = @"http://www.google.com"}},
742
"List", new List<UrlStatus>
744
new UrlStatus {Status = 300, Url = @"http://www.yahoo.com"},
745
new UrlStatus {Status = 200, Url = @"http://www.askjeeves.com"}
750
string json = JsonConvert.SerializeObject(collection, Formatting.Indented, new JsonSerializerSettings
752
TypeNameHandling = TypeNameHandling.All,
753
TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
756
string urlStatusTypeName = ReflectionUtils.GetTypeName(typeof (UrlStatus), FormatterAssemblyStyle.Simple);
759
""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"",
761
""$type"": """ + urlStatusTypeName + @""",
763
""Url"": ""http://www.bing.com""
766
""$type"": """ + urlStatusTypeName + @""",
768
""Url"": ""http://www.google.com""
771
""$type"": ""System.Collections.Generic.List`1[[" + urlStatusTypeName + @"]], mscorlib"",
774
""$type"": """ + urlStatusTypeName + @""",
776
""Url"": ""http://www.yahoo.com""
779
""$type"": """ + urlStatusTypeName + @""",
781
""Url"": ""http://www.askjeeves.com""
787
object c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings
789
TypeNameHandling = TypeNameHandling.All,
790
TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
793
CustomAssert.IsInstanceOfType(typeof (Dictionary<string, object>), c);
795
Dictionary<string, object> newCollection = (Dictionary<string, object>) c;
796
Assert.AreEqual(3, newCollection.Count);
797
Assert.AreEqual(@"http://www.bing.com", ((UrlStatus) newCollection["First"]).Url);
799
List<UrlStatus> statues = (List<UrlStatus>) newCollection["List"];
800
Assert.AreEqual(2, statues.Count);
805
public void SerializingIEnumerableOfTShouldRetainGenericTypeInfo()
807
string productClassRef = ReflectionUtils.GetTypeName(typeof (Product[]), FormatterAssemblyStyle.Simple);
809
CustomEnumerable<Product> products = new CustomEnumerable<Product>();
811
string json = JsonConvert.SerializeObject(products, Formatting.Indented, new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.All});
814
""$type"": """ + productClassRef + @""",
819
public class CustomEnumerable<T> : IEnumerable<T>
821
//NOTE: a simple linked list
822
private readonly T value;
823
private readonly CustomEnumerable<T> next;
824
private readonly int count;
826
private CustomEnumerable(T value, CustomEnumerable<T> next)
830
count = this.next.count + 1;
833
public CustomEnumerable()
838
public CustomEnumerable<T> AddFirst(T newVal)
840
return new CustomEnumerable<T>(newVal, this);
843
public IEnumerator<T> GetEnumerator()
845
if (count == 0) // last node
849
var nextInLine = next;
850
while (nextInLine != null)
852
if (nextInLine.count != 0)
853
yield return nextInLine.value;
854
nextInLine = nextInLine.next;
858
IEnumerator IEnumerable.GetEnumerator()
860
return GetEnumerator();
867
public string Model { get; set; }
868
public DateTime Year { get; set; }
869
public List<string> Features { get; set; }
870
public object[] Objects { get; set; }
874
public DateTime LastModified { get; set; }
878
public void ByteArrays()
880
Car testerObject = new Car();
881
testerObject.Year = new DateTime(2000, 10, 5, 1, 1, 1, DateTimeKind.Utc);
882
byte[] data = new byte[] {75, 65, 82, 73, 82, 65};
883
testerObject.Objects = new object[] {data, "prueba"};
885
JsonSerializerSettings jsonSettings = new JsonSerializerSettings();
886
jsonSettings.NullValueHandling = NullValueHandling.Ignore;
887
jsonSettings.TypeNameHandling = TypeNameHandling.All;
889
string output = JsonConvert.SerializeObject(testerObject, Formatting.Indented, jsonSettings);
891
string carClassRef = ReflectionUtils.GetTypeName(typeof (Car), FormatterAssemblyStyle.Simple);
893
Assert.AreEqual(output, @"{
894
""$type"": """ + carClassRef + @""",
895
""Year"": ""2000-10-05T01:01:01Z"",
897
""$type"": ""System.Object[], mscorlib"",
900
""$type"": ""System.Byte[], mscorlib"",
901
""$value"": ""S0FSSVJB""
907
Car obj = JsonConvert.DeserializeObject<Car>(output, jsonSettings);
909
Assert.IsNotNull(obj);
911
Assert.IsTrue(obj.Objects[0] is byte[]);
913
byte[] d = (byte[]) obj.Objects[0];
914
CollectionAssert.AreEquivalent(data, d);
917
#if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE)
919
public void ISerializableTypeNameHandlingTest()
921
//Create an instance of our example type
922
IExample e = new Example("Rob");
924
SerializableWrapper w = new SerializableWrapper
929
//Test Binary Serialization Round Trip
930
//This will work find because the Binary Formatter serializes type names
931
//this.TestBinarySerializationRoundTrip(e);
933
//Test Json Serialization
934
//This fails because the JsonSerializer doesn't serialize type names correctly for ISerializable objects
935
//Type Names should be serialized for All, Auto and Object modes
936
this.TestJsonSerializationRoundTrip(w, TypeNameHandling.All);
937
this.TestJsonSerializationRoundTrip(w, TypeNameHandling.Auto);
938
this.TestJsonSerializationRoundTrip(w, TypeNameHandling.Objects);
941
private void TestJsonSerializationRoundTrip(SerializableWrapper e, TypeNameHandling flag)
943
Console.WriteLine("Type Name Handling: " + flag.ToString());
944
StringWriter writer = new StringWriter();
946
//Create our serializer and set Type Name Handling appropriately
947
JsonSerializer serializer = new JsonSerializer();
948
serializer.TypeNameHandling = flag;
950
//Do the actual serialization and dump to Console for inspection
951
serializer.Serialize(new JsonTextWriter(writer), e);
952
Console.WriteLine(writer.ToString());
955
//Now try to deserialize
956
//Json.Net will cause an error here as it will try and instantiate
957
//the interface directly because it failed to respect the
958
//TypeNameHandling property on serialization
959
SerializableWrapper f = serializer.Deserialize<SerializableWrapper>(new JsonTextReader(new StringReader(writer.ToString())));
962
Assert.AreEqual(e, f, "Objects should be equal after round trip json serialization");
966
#if !(NET20 || NET35)
968
public void SerializationBinderWithFullName()
970
Message message = new Message
972
Address = "jamesnk@testtown.com",
973
Body = new Version(1, 2, 3, 4)
976
string json = JsonConvert.SerializeObject(message, Formatting.Indented, new JsonSerializerSettings
978
TypeNameHandling = TypeNameHandling.All,
979
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full,
980
Binder = new MetroBinder(),
981
ContractResolver = new DefaultContractResolver
983
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
984
IgnoreSerializableAttribute = true
990
""$type"": "":::MESSAGE:::, AssemblyName"",
991
""Address"": ""jamesnk@testtown.com"",
993
""$type"": "":::VERSION:::, AssemblyName"",
998
""MajorRevision"": 0,
1004
public class MetroBinder : SerializationBinder
1006
public override Type BindToType(string assemblyName, string typeName)
1011
public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
1013
assemblyName = "AssemblyName";
1015
typeName = ":::" + serializedType.Name.ToUpper(CultureInfo.InvariantCulture) + ":::";
1017
typeName = ":::" + serializedType.Name.ToUpper() + ":::";
1024
public void TypeNameIntList()
1026
TypeNameList<int> l = new TypeNameList<int>();
1031
string json = JsonConvert.SerializeObject(l, Formatting.Indented);
1040
public void TypeNameComponentList()
1042
var c1 = new TestComponentSimple();
1044
TypeNameList<object> l = new TypeNameList<object>();
1048
BirthDate = new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc),
1049
Department = "Department!"
1052
l.Add(long.MaxValue);
1054
string json = JsonConvert.SerializeObject(l, Formatting.Indented);
1057
""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
1061
""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee, Newtonsoft.Json.Tests"",
1062
""FirstName"": null,
1064
""BirthDate"": ""2000-12-12T12:12:12Z"",
1065
""Department"": ""Department!"",
1072
TypeNameList<object> l2 = JsonConvert.DeserializeObject<TypeNameList<object>>(json);
1073
Assert.AreEqual(4, l2.Count);
1075
CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), l2[0]);
1076
CustomAssert.IsInstanceOfType(typeof (Employee), l2[1]);
1077
CustomAssert.IsInstanceOfType(typeof (string), l2[2]);
1078
CustomAssert.IsInstanceOfType(typeof (long), l2[3]);
1082
public void TypeNameDictionary()
1084
TypeNameDictionary<object> l = new TypeNameDictionary<object>();
1085
l.Add("First", new TestComponentSimple {MyProperty = 1});
1086
l.Add("Second", "String!");
1087
l.Add("Third", long.MaxValue);
1089
string json = JsonConvert.SerializeObject(l, Formatting.Indented);
1092
""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
1095
""Second"": ""String!"",
1096
""Third"": 9223372036854775807
1099
TypeNameDictionary<object> l2 = JsonConvert.DeserializeObject<TypeNameDictionary<object>>(json);
1100
Assert.AreEqual(3, l2.Count);
1102
CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), l2["First"]);
1103
Assert.AreEqual(1, ((TestComponentSimple) l2["First"]).MyProperty);
1104
CustomAssert.IsInstanceOfType(typeof (string), l2["Second"]);
1105
CustomAssert.IsInstanceOfType(typeof (long), l2["Third"]);
1109
public void TypeNameObjectItems()
1111
TypeNameObject o1 = new TypeNameObject();
1113
o1.Object1 = new TestComponentSimple {MyProperty = 1};
1115
o1.ObjectNotHandled = new TestComponentSimple {MyProperty = int.MaxValue};
1116
o1.String = "String!";
1117
o1.Integer = int.MaxValue;
1119
string json = JsonConvert.SerializeObject(o1, Formatting.Indented);
1120
string expected = @"{
1122
""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
1126
""ObjectNotHandled"": {
1127
""MyProperty"": 2147483647
1129
""String"": ""String!"",
1130
""Integer"": 2147483647
1132
Assert.AreEqual(expected, json);
1134
TypeNameObject o2 = JsonConvert.DeserializeObject<TypeNameObject>(json);
1135
Assert.IsNotNull(o2);
1137
CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), o2.Object1);
1138
Assert.AreEqual(1, ((TestComponentSimple) o2.Object1).MyProperty);
1139
CustomAssert.IsInstanceOfType(typeof (long), o2.Object2);
1140
CustomAssert.IsInstanceOfType(typeof (JObject), o2.ObjectNotHandled);
1142
""MyProperty"": 2147483647
1143
}", o2.ObjectNotHandled.ToString());
1147
public void PropertyItemTypeNameHandling()
1149
PropertyItemTypeNameHandling c1 = new PropertyItemTypeNameHandling();
1150
c1.Data = new List<object>
1154
new TestComponentSimple {MyProperty = 1}
1157
string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
1163
""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
1169
PropertyItemTypeNameHandling c2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandling>(json);
1170
Assert.AreEqual(3, c2.Data.Count);
1172
CustomAssert.IsInstanceOfType(typeof (long), c2.Data[0]);
1173
CustomAssert.IsInstanceOfType(typeof (string), c2.Data[1]);
1174
CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), c2.Data[2]);
1175
TestComponentSimple c = (TestComponentSimple) c2.Data[2];
1176
Assert.AreEqual(1, c.MyProperty);
1180
public void PropertyItemTypeNameHandlingNestedCollections()
1182
PropertyItemTypeNameHandling c1 = new PropertyItemTypeNameHandling
1184
Data = new List<object>
1186
new TestComponentSimple {MyProperty = 1},
1197
string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
1201
""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
1205
""$type"": ""System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib"",
1215
PropertyItemTypeNameHandling c2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandling>(json);
1216
Assert.AreEqual(2, c2.Data.Count);
1218
CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), c2.Data[0]);
1219
CustomAssert.IsInstanceOfType(typeof (List<object>), c2.Data[1]);
1220
List<object> c = (List<object>) c2.Data[1];
1221
CustomAssert.IsInstanceOfType(typeof (JArray), c[0]);
1226
""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
1230
""$type"": ""System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib"",
1233
""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
1241
c2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandling>(json);
1242
Assert.AreEqual(2, c2.Data.Count);
1244
CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), c2.Data[0]);
1245
CustomAssert.IsInstanceOfType(typeof (List<object>), c2.Data[1]);
1246
c = (List<object>) c2.Data[1];
1247
CustomAssert.IsInstanceOfType(typeof (JObject), c[0]);
1248
JObject o = (JObject) c[0];
1249
Assert.AreEqual(1, (int) o["MyProperty"]);
1253
public void PropertyItemTypeNameHandlingNestedDictionaries()
1255
PropertyItemTypeNameHandlingDictionary c1 = new PropertyItemTypeNameHandlingDictionary()
1257
Data = new Dictionary<string, object>
1260
"one", new TestComponentSimple {MyProperty = 1}
1263
"two", new Dictionary<string, object>
1266
"one", new Dictionary<string, object>
1276
string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
1280
""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
1284
""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"",
1292
PropertyItemTypeNameHandlingDictionary c2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandlingDictionary>(json);
1293
Assert.AreEqual(2, c2.Data.Count);
1295
CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), c2.Data["one"]);
1296
CustomAssert.IsInstanceOfType(typeof(Dictionary<string, object>), c2.Data["two"]);
1297
Dictionary<string, object> c = (Dictionary<string, object>)c2.Data["two"];
1298
CustomAssert.IsInstanceOfType(typeof (JObject), c["one"]);
1303
""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
1307
""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"",
1309
""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
1316
c2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandlingDictionary>(json);
1317
Assert.AreEqual(2, c2.Data.Count);
1319
CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), c2.Data["one"]);
1320
CustomAssert.IsInstanceOfType(typeof(Dictionary<string, object>), c2.Data["two"]);
1321
c = (Dictionary<string, object>)c2.Data["two"];
1322
CustomAssert.IsInstanceOfType(typeof(JObject), c["one"]);
1324
JObject o = (JObject) c["one"];
1325
Assert.AreEqual(1, (int) o["MyProperty"]);
1329
public void PropertyItemTypeNameHandlingObject()
1331
PropertyItemTypeNameHandlingObject o1 = new PropertyItemTypeNameHandlingObject
1333
Data = new TypeNameHandlingTestObject
1335
Prop1 = new List<object>
1337
new TestComponentSimple
1342
Prop2 = new TestComponentSimple
1347
Prop4 = new JObject()
1351
string json = JsonConvert.SerializeObject(o1, Formatting.Indented);
1355
""$type"": ""System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib"",
1363
""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
1371
PropertyItemTypeNameHandlingObject o2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandlingObject>(json);
1372
Assert.IsNotNull(o2);
1373
Assert.IsNotNull(o2.Data);
1375
CustomAssert.IsInstanceOfType(typeof(List<object>), o2.Data.Prop1);
1376
CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), o2.Data.Prop2);
1377
CustomAssert.IsInstanceOfType(typeof(long), o2.Data.Prop3);
1378
CustomAssert.IsInstanceOfType(typeof(JObject), o2.Data.Prop4);
1380
List<object> o = (List<object>)o2.Data.Prop1;
1381
JObject j = (JObject)o[0];
1382
Assert.AreEqual(1, (int)j["MyProperty"]);
1385
#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
1387
public void PropertyItemTypeNameHandlingDynamic()
1389
PropertyItemTypeNameHandlingDynamic d1 = new PropertyItemTypeNameHandlingDynamic();
1391
dynamic data = new DynamicDictionary();
1392
data.one = new TestComponentSimple
1397
dynamic data2 = new DynamicDictionary();
1398
data2.one = new TestComponentSimple
1405
d1.Data = (DynamicDictionary)data;
1407
string json = JsonConvert.SerializeObject(d1, Formatting.Indented);
1411
""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
1415
""$type"": ""Newtonsoft.Json.Tests.Linq.DynamicDictionary, Newtonsoft.Json.Tests"",
1423
PropertyItemTypeNameHandlingDynamic d2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandlingDynamic>(json);
1424
Assert.IsNotNull(d2);
1425
Assert.IsNotNull(d2.Data);
1427
dynamic data3 = d2.Data;
1428
TestComponentSimple c = (TestComponentSimple)data3.one;
1429
Assert.AreEqual(1, c.MyProperty);
1431
dynamic data4 = data3.two;
1432
JObject o = (JObject)data4.one;
1433
Assert.AreEqual(2, (int)o["MyProperty"]);
1438
""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
1442
""$type"": ""Newtonsoft.Json.Tests.Linq.DynamicDictionary, Newtonsoft.Json.Tests"",
1444
""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
1451
d2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandlingDynamic>(json);
1454
o = (JObject)data4.one;
1455
Assert.AreEqual(2, (int)o["MyProperty"]);
1460
public class Message
1462
public string Address { get; set; }
1464
[JsonProperty(TypeNameHandling = TypeNameHandling.All)]
1465
public object Body { get; set; }
1468
public class SearchDetails
1470
public string Query { get; set; }
1471
public string Language { get; set; }
1474
public class Customer
1476
public string Name { get; set; }
1479
public class Purchase
1481
public string ProductName { get; set; }
1482
public decimal Price { get; set; }
1483
public int Quantity { get; set; }
1486
#if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE)
1487
public class SerializableWrapper
1489
public object Content { get; set; }
1491
public override bool Equals(object obj)
1493
SerializableWrapper w = obj as SerializableWrapper;
1498
return Equals(w.Content, Content);
1501
public override int GetHashCode()
1503
if (Content == null)
1506
return Content.GetHashCode();
1510
public interface IExample
1520
public class Example
1523
public Example(String name)
1528
protected Example(SerializationInfo info, StreamingContext context)
1530
this.Name = info.GetString("name");
1533
public void GetObjectData(SerializationInfo info, StreamingContext context)
1535
info.AddValue("name", this.Name);
1538
public String Name { get; set; }
1540
public override bool Equals(object obj)
1542
if (obj == null) return false;
1543
if (ReferenceEquals(this, obj)) return true;
1544
if (obj is IExample)
1546
return this.Name.Equals(((IExample)obj).Name);
1554
public override int GetHashCode()
1559
return Name.GetHashCode();
1564
public class PropertyItemTypeNameHandlingObject
1566
[JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)]
1567
public TypeNameHandlingTestObject Data { get; set; }
1570
#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
1571
public class PropertyItemTypeNameHandlingDynamic
1573
[JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)]
1574
public DynamicDictionary Data { get; set; }
1578
public class TypeNameHandlingTestObject
1580
public object Prop1 { get; set; }
1581
public object Prop2 { get; set; }
1582
public object Prop3 { get; set; }
1583
public object Prop4 { get; set; }
1586
public class PropertyItemTypeNameHandlingDictionary
1588
[JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)]
1589
public IDictionary<string, object> Data { get; set; }
1592
public class PropertyItemTypeNameHandling
1594
[JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)]
1595
public IList<object> Data { get; set; }
1598
[JsonArray(ItemTypeNameHandling = TypeNameHandling.All)]
1599
public class TypeNameList<T> : List<T>
1603
[JsonDictionary(ItemTypeNameHandling = TypeNameHandling.All)]
1604
public class TypeNameDictionary<T> : Dictionary<string, T>
1608
[JsonObject(ItemTypeNameHandling = TypeNameHandling.All)]
1609
public class TypeNameObject
1611
public object Object1 { get; set; }
1612
public object Object2 { get; set; }
1613
[JsonProperty(TypeNameHandling = TypeNameHandling.None)]
1614
public object ObjectNotHandled { get; set; }
1615
public string String { get; set; }
1616
public int Integer { get; set; }
b'\\ No newline at end of file'