From e156978055e7f5833686a8282ba16f73edb04f2f Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Sun, 22 Jul 2012 12:49:17 +1200 Subject: [PATCH] -Included missing documentation code files --- .../ConvertingJsonAndXmlTests.cs | 137 +++ .../Documentation/LinqToJsonTests.cs | 341 +++++++ .../ReadingAndWritingJsonTests.cs | 109 +++ .../Documentation/SerializationTests.cs | 887 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- 6 files changed, 1476 insertions(+), 2 deletions(-) create mode 100644 Src/Newtonsoft.Json.Tests/Documentation/ConvertingJsonAndXmlTests.cs create mode 100644 Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs create mode 100644 Src/Newtonsoft.Json.Tests/Documentation/ReadingAndWritingJsonTests.cs create mode 100644 Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs diff --git a/Src/Newtonsoft.Json.Tests/Documentation/ConvertingJsonAndXmlTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/ConvertingJsonAndXmlTests.cs new file mode 100644 index 00000000..e4b95731 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/Documentation/ConvertingJsonAndXmlTests.cs @@ -0,0 +1,137 @@ +#region License +// Copyright (c) 2007 James Newton-King +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +#endregion + +#if !(NET35 || NET20 || PORTABLE) +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Dynamic; +using System.IO; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Xml; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +#if !NETFX_CORE +using NUnit.Framework; +#else +using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; +using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; +using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; +#endif +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json.Tests.TestObjects; +using Newtonsoft.Json.Utilities; +using System.Globalization; +using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs; + +namespace Newtonsoft.Json.Tests.Documentation +{ + public class ConvertingJsonAndXmlTests + { + public void SerializeXmlNode() + { + #region SerializeXmlNode + string xml = @" + + + Alan + http://www.google.com + + + Louis + http://www.yahoo.com + + "; + + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); + + string jsonText = JsonConvert.SerializeXmlNode(doc); + //{ + // "?xml": { + // "@version": "1.0", + // "@standalone": "no" + // }, + // "root": { + // "person": [ + // { + // "@id": "1", + // "name": "Alan", + // "url": "http://www.google.com" + // }, + // { + // "@id": "2", + // "name": "Louis", + // "url": "http://www.yahoo.com" + // } + // ] + // } + //} + #endregion + } + + public void DeserializeXmlNode() + { + #region DeserializeXmlNode + string json = @"{ + '?xml': { + '@version': '1.0', + '@standalone': 'no' + }, + 'root': { + 'person': [ + { + '@id': '1', + 'name': 'Alan', + 'url': 'http://www.google.com' + }, + { + '@id': '2', + 'name': 'Louis', + 'url': 'http://www.yahoo.com' + } + ] + } + }"; + + XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(json); + // + // + // + // Alan + // http://www.google.com + // + // + // Louis + // http://www.yahoo.com + // + // + #endregion + } + } +} +#endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs new file mode 100644 index 00000000..f316c4d1 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs @@ -0,0 +1,341 @@ +#region License +// Copyright (c) 2007 James Newton-King +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +#endregion + +#if !(NET35 || NET20 || PORTABLE) +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Dynamic; +using System.IO; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +#if !NETFX_CORE +using NUnit.Framework; +#else +using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; +using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; +using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; +#endif +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json.Tests.TestObjects; +using Newtonsoft.Json.Utilities; +using System.Globalization; +using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs; + +namespace Newtonsoft.Json.Tests.Documentation +{ + public class LinqToJsonTests + { + public void LinqToJsonCreateNormal() + { + #region LinqToJsonCreateNormal + JArray array = new JArray(); + JValue text = new JValue("Manual text"); + JValue date = new JValue(new DateTime(2000, 5, 23)); + + array.Add(text); + array.Add(date); + + string json = array.ToString(); + // [ + // "Manual text", + // "\/Date(958996800000+1200)\/" + // ] + #endregion + } + + public class Post + { + public string Title { get; set; } + public string Description { get; set; } + public string Link { get; set; } + public IList Categories { get; set; } + } + + private List GetPosts() + { + return null; + } + + public void LinqToJsonCreateDeclaratively() + { + #region LinqToJsonCreateDeclaratively + List posts = GetPosts(); + + JObject rss = + new JObject( + new JProperty("channel", + new JObject( + new JProperty("title", "James Newton-King"), + new JProperty("link", "http://james.newtonking.com"), + new JProperty("description", "James Newton-King's blog."), + new JProperty("item", + new JArray( + from p in posts + orderby p.Title + select new JObject( + new JProperty("title", p.Title), + new JProperty("description", p.Description), + new JProperty("link", p.Link), + new JProperty("category", + new JArray( + from c in p.Categories + select new JValue(c))))))))); + + Console.WriteLine(rss.ToString()); + + //{ + // "channel": { + // "title": "James Newton-King", + // "link": "http://james.newtonking.com", + // "description": "James Newton-King's blog.", + // "item": [ + // { + // "title": "Json.NET 1.3 + New license + Now on CodePlex", + // "description": "Annoucing the release of Json.NET 1.3, the MIT license and the source being available on CodePlex", + // "link": "http://james.newtonking.com/projects/json-net.aspx", + // "category": [ + // "Json.NET", + // "CodePlex" + // ] + // }, + // { + // "title": "LINQ to JSON beta", + // "description": "Annoucing LINQ to JSON", + // "link": "http://james.newtonking.com/projects/json-net.aspx", + // "category": [ + // "Json.NET", + // "LINQ" + // ] + // } + // ] + // } + //} + #endregion + } + + public void LinqToJsonCreateFromObject() + { + List posts = null; + + #region LinqToJsonCreateFromObject + JObject o = JObject.FromObject(new + { + channel = new + { + title = "James Newton-King", + link = "http://james.newtonking.com", + description = "James Newton-King's blog.", + item = + from p in posts + orderby p.Title + select new + { + title = p.Title, + description = p.Description, + link = p.Link, + category = p.Categories + } + } + }); + #endregion + } + + public void LinqToJsonCreateParse() + { + #region LinqToJsonCreateParse + string json = @"{ + CPU: 'Intel', + Drives: [ + 'DVD read/writer', + ""500 gigabyte hard drive"" + ] + }"; + + JObject o = JObject.Parse(json); + #endregion + } + + public void LinqToJsonQuerying() + { + JObject rss = new JObject(); + + #region LinqToJsonQuerying + var postTitles = + from p in rss["channel"]["item"].Children() + select (string)p["title"]; + + foreach (var item in postTitles) + { + Console.WriteLine(item); + } + + //LINQ to JSON beta + //Json.NET 1.3 + New license + Now on CodePlex + + var categories = + from c in rss["channel"]["item"].Children()["category"].Values() + group c by c into g + orderby g.Count() descending + select new { Category = g.Key, Count = g.Count() }; + + foreach (var c in categories) + { + Console.WriteLine(c.Category + " - Count: " + c.Count); + } + + //Json.NET - Count: 2 + //LINQ - Count: 1 + //CodePlex - Count: 1 + #endregion + } + + #region LinqToJsonDeserializeObject + public class Shortie + { + public string Original { get; set; } + public string Shortened { get; set; } + public string Short { get; set; } + public ShortieException Error { get; set; } + } + + public class ShortieException + { + public int Code { get; set; } + public string ErrorMessage { get; set; } + } + #endregion + + public void LinqToJsonDeserializeExample() + { + #region LinqToJsonDeserializeExample + string jsonText = @"{ + 'short': { + 'original': 'http://www.foo.com/', + 'short': 'krehqk', + 'error': { + 'code':0, + 'msg':'No action taken' + } + }"; + + JObject json = JObject.Parse(jsonText); + + Shortie shortie = new Shortie + { + Original = (string)json["short"]["original"], + Short = (string)json["short"]["short"], + Error = new ShortieException + { + Code = (int)json["short"]["error"]["code"], + ErrorMessage = (string)json["short"]["error"]["msg"] + } + }; + + Console.WriteLine(shortie.Original); + // http://www.foo.com/ + + Console.WriteLine(shortie.Error.ErrorMessage); + // No action taken + #endregion + } + + public void SelectTokenSimple() + { + JObject o = new JObject(); + + #region SelectTokenSimple + string name = (string)o.SelectToken("Manufacturers[0].Name"); + #endregion + } + + public void SelectTokenComplex() + { + #region SelectTokenComplex + JObject o = JObject.Parse(@"{ + 'Stores': [ + 'Lambton Quay', + 'Willis Street' + ], + 'Manufacturers': [ + { + 'Name': 'Acme Co', + 'Products': [ + { + 'Name': 'Anvil', + 'Price': 50 + } + ] + }, + { + 'Name': 'Contoso', + 'Products': [ + { + 'Name': 'Elbow Grease', + 'Price': 99.95 + }, + { + 'Name': 'Headlight Fluid', + 'Price': 4 + } + ] + } + ] + }"); + + string name = (string)o.SelectToken("Manufacturers[0].Name"); + // Acme Co + + decimal productPrice = (decimal)o.SelectToken("Manufacturers[0].Products[0].Price"); + // 50 + + string productName = (string)o.SelectToken("Manufacturers[1].Products[0].Name"); + // Elbow Grease + #endregion + } + + public void SelectTokenLinq() + { + JObject o = new JObject(); + + #region SelectTokenLinq + IList storeNames = o.SelectToken("Stores").Select(s => (string)s).ToList(); + // Lambton Quay + // Willis Street + + IList firstProductNames = o["Manufacturers"].Select(m => (string)m.SelectToken("Products[1].Name")).ToList(); + // null + // Headlight Fluid + + decimal totalPrice = o["Manufacturers"].Sum(m => (decimal)m.SelectToken("Products[0].Price")); + // 149.95 + #endregion + } + } +} +#endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/ReadingAndWritingJsonTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/ReadingAndWritingJsonTests.cs new file mode 100644 index 00000000..def2b0af --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/Documentation/ReadingAndWritingJsonTests.cs @@ -0,0 +1,109 @@ +#region License +// Copyright (c) 2007 James Newton-King +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +#endregion + +#if !(NET35 || NET20 || PORTABLE) +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Dynamic; +using System.IO; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +#if !NETFX_CORE +using NUnit.Framework; +#else +using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; +using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; +using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; +#endif +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json.Tests.TestObjects; +using Newtonsoft.Json.Utilities; +using System.Globalization; +using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs; + +namespace Newtonsoft.Json.Tests.Documentation +{ + public class ReadingAndWritingJsonTests + { + public void ReadingAndWritingJsonText() + { + #region ReadingAndWritingJsonText + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); + + using (JsonWriter writer = new JsonTextWriter(sw)) + { + writer.Formatting = Formatting.Indented; + + writer.WriteStartObject(); + writer.WritePropertyName("CPU"); + writer.WriteValue("Intel"); + writer.WritePropertyName("PSU"); + writer.WriteValue("500W"); + writer.WritePropertyName("Drives"); + writer.WriteStartArray(); + writer.WriteValue("DVD read/writer"); + writer.WriteComment("(broken)"); + writer.WriteValue("500 gigabyte hard drive"); + writer.WriteValue("200 gigabype hard drive"); + writer.WriteEnd(); + writer.WriteEndObject(); + } + + // { + // "CPU": "Intel", + // "PSU": "500W", + // "Drives": [ + // "DVD read/writer" + // /*(broken)*/, + // "500 gigabyte hard drive", + // "200 gigabype hard drive" + // ] + // } + #endregion + } + + public void ReadingAndWritingJsonLinq() + { + #region ReadingAndWritingJsonLinq + JObject o = new JObject( + new JProperty("Name", "John Smith"), + new JProperty("BirthDate", new DateTime(1983, 3, 20)) + ); + + JsonSerializer serializer = new JsonSerializer(); + Person p = (Person)serializer.Deserialize(new JTokenReader(o), typeof(Person)); + + Console.WriteLine(p.Name); + // John Smith + #endregion + } + } +} +#endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs new file mode 100644 index 00000000..908c48b8 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs @@ -0,0 +1,887 @@ +#region License +// Copyright (c) 2007 James Newton-King +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +#endregion + +#if !(NET35 || NET20 || PORTABLE) +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Dynamic; +using System.IO; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +#if !NETFX_CORE +using NUnit.Framework; +#else +using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; +using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; +using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; +#endif +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json.Tests.TestObjects; +using Newtonsoft.Json.Utilities; +using System.Globalization; +using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs; + +namespace Newtonsoft.Json.Tests.Documentation +{ + public class SerializationTests + { + public void SerializeObject() + { + #region SerializeObject + Product product = new Product(); + + product.Name = "Apple"; + product.ExpiryDate = new DateTime(2008, 12, 28); + product.Price = 3.99M; + product.Sizes = new string[] { "Small", "Medium", "Large" }; + + string output = JsonConvert.SerializeObject(product); + //{ + // "Name": "Apple", + // "ExpiryDate": "2008-12-28T00:00:00", + // "Price": 3.99, + // "Sizes": [ + // "Small", + // "Medium", + // "Large" + // ] + //} + + Product deserializedProduct = JsonConvert.DeserializeObject(output); + #endregion + } + + public void JsonSerializerToStream() + { + #region JsonSerializerToStream + Product product = new Product(); + product.ExpiryDate = new DateTime(2008, 12, 28); + + JsonSerializer serializer = new JsonSerializer(); + serializer.Converters.Add(new JavaScriptDateTimeConverter()); + serializer.NullValueHandling = NullValueHandling.Ignore; + + using (StreamWriter sw = new StreamWriter(@"c:\json.txt")) + using (JsonWriter writer = new JsonTextWriter(sw)) + { + serializer.Serialize(writer, product); + // {"ExpiryDate":new Date(1230375600000),"Price":0} + } + #endregion + } + + #region SerializationAttributes + [JsonObject(MemberSerialization.OptIn)] + public class Person + { + // "John Smith" + [JsonProperty] + public string Name { get; set; } + + // "2000-12-15T22:11:03" + [JsonProperty] + public DateTime BirthDate { get; set; } + + // new Date(976918263055) + [JsonProperty] + [JsonConverter(typeof(JavaScriptDateTimeConverter))] + public DateTime LastModified { get; set; } + + // not serialized because mode is opt-in + public string Department { get; set; } + } + #endregion + +#region SerializationCallbacksObject +public class SerializationEventTestObject +{ + // 2222 + // This member is serialized and deserialized with no change. + public int Member1 { get; set; } + + // The value of this field is set and reset during and + // after serialization. + public string Member2 { get; set; } + + // This field is not serialized. The OnDeserializedAttribute + // is used to set the member value after serialization. + [JsonIgnore] + public string Member3 { get; set; } + + // This field is set to null, but populated after deserialization. + public string Member4 { get; set; } + + public SerializationEventTestObject() + { + Member1 = 11; + Member2 = "Hello World!"; + Member3 = "This is a nonserialized value"; + Member4 = null; + } + + [OnSerializing] + internal void OnSerializingMethod(StreamingContext context) + { + Member2 = "This value went into the data file during serialization."; + } + + [OnSerialized] + internal void OnSerializedMethod(StreamingContext context) + { + Member2 = "This value was reset after serialization."; + } + + [OnDeserializing] + internal void OnDeserializingMethod(StreamingContext context) + { + Member3 = "This value was set during deserialization"; + } + + [OnDeserialized] + internal void OnDeserializedMethod(StreamingContext context) + { + Member4 = "This value was set after deserialization."; + } +} +#endregion + + public void SerializationCallbacksExample() + { + #region SerializationCallbacksExample + SerializationEventTestObject obj = new SerializationEventTestObject(); + + Console.WriteLine(obj.Member1); + // 11 + Console.WriteLine(obj.Member2); + // Hello World! + Console.WriteLine(obj.Member3); + // This is a nonserialized value + Console.WriteLine(obj.Member4); + // null + + string json = JsonConvert.SerializeObject(obj, Formatting.Indented); + // { + // "Member1": 11, + // "Member2": "This value went into the data file during serialization.", + // "Member4": null + // } + + Console.WriteLine(obj.Member1); + // 11 + Console.WriteLine(obj.Member2); + // This value was reset after serialization. + Console.WriteLine(obj.Member3); + // This is a nonserialized value + Console.WriteLine(obj.Member4); + // null + + obj = JsonConvert.DeserializeObject(json); + + Console.WriteLine(obj.Member1); + // 11 + Console.WriteLine(obj.Member2); + // This value went into the data file during serialization. + Console.WriteLine(obj.Member3); + // This value was set during deserialization + Console.WriteLine(obj.Member4); + // This value was set after deserialization. + #endregion + } + + public void SerializationErrorHandling() + { + #region SerializationErrorHandling + List errors = new List(); + + List c = JsonConvert.DeserializeObject>(@"[ + '2009-09-09T00:00:00Z', + 'I am not a date and will error!', + [ + 1 + ], + '1977-02-20T00:00:00Z', + null, + '2000-12-01T00:00:00Z' + ]", + new JsonSerializerSettings + { + Error = delegate(object sender, ErrorEventArgs args) + { + errors.Add(args.ErrorContext.Error.Message); + args.ErrorContext.Handled = true; + }, + Converters = { new IsoDateTimeConverter() } + }); + + // 2009-09-09T00:00:00Z + // 1977-02-20T00:00:00Z + // 2000-12-01T00:00:00Z + + // The string was not recognized as a valid DateTime. There is a unknown word starting at index 0. + // Unexpected token parsing date. Expected String, got StartArray. + // Cannot convert null value to System.DateTime. + #endregion + } + + public void SerializationErrorHandlingWithParent() + { + #region SerializationErrorHandlingWithParent + List errors = new List(); + + JsonSerializer serializer = new JsonSerializer(); + serializer.Error += delegate(object sender, ErrorEventArgs args) + { + // only log an error once + if (args.CurrentObject == args.ErrorContext.OriginalObject) + errors.Add(args.ErrorContext.Error.Message); + }; + #endregion + } + + #region SerializationErrorHandlingAttributeObject + public class PersonError + { + private List _roles; + + public string Name { get; set; } + public int Age { get; set; } + public List Roles + { + get + { + if (_roles == null) + throw new Exception("Roles not loaded!"); + + return _roles; + } + set { _roles = value; } + } + public string Title { get; set; } + + [OnError] + internal void OnError(StreamingContext context, ErrorContext errorContext) + { + errorContext.Handled = true; + } + } + #endregion + + public void SerializationErrorHandlingAttributeExample() + { + #region SerializationErrorHandlingAttributeExample + PersonError person = new PersonError + { + Name = "George Michael Bluth", + Age = 16, + Roles = null, + Title = "Mister Manager" + }; + + string json = JsonConvert.SerializeObject(person, Formatting.Indented); + + Console.WriteLine(json); + //{ + // "Name": "George Michael Bluth", + // "Age": 16, + // "Title": "Mister Manager" + //} + #endregion + } + + public void PreservingObjectReferencesOff() + { + #region PreservingObjectReferencesOff + Person p = new Person + { + BirthDate = new DateTime(1980, 12, 23, 0, 0, 0, DateTimeKind.Utc), + LastModified = new DateTime(2009, 2, 20, 12, 59, 21, DateTimeKind.Utc), + Name = "James" + }; + + List people = new List(); + people.Add(p); + people.Add(p); + + string json = JsonConvert.SerializeObject(people, Formatting.Indented); + //[ + // { + // "Name": "James", + // "BirthDate": "\/Date(346377600000)\/", + // "LastModified": "\/Date(1235134761000)\/" + // }, + // { + // "Name": "James", + // "BirthDate": "\/Date(346377600000)\/", + // "LastModified": "\/Date(1235134761000)\/" + // } + //] + #endregion + } + + public void PreservingObjectReferencesOn() + { + List people = new List(); + + #region PreservingObjectReferencesOn + string json = JsonConvert.SerializeObject(people, Formatting.Indented, + new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }); + + //[ + // { + // "$id": "1", + // "Name": "James", + // "BirthDate": "\/Date(346377600000)\/", + // "LastModified": "\/Date(1235134761000)\/" + // }, + // { + // "$ref": "1" + // } + //] + + List deserializedPeople = JsonConvert.DeserializeObject>(json, + new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }); + + Console.WriteLine(deserializedPeople.Count); + // 2 + + Person p1 = deserializedPeople[0]; + Person p2 = deserializedPeople[1]; + + Console.WriteLine(p1.Name); + // James + Console.WriteLine(p2.Name); + // James + + bool equal = Object.ReferenceEquals(p1, p2); + // true + #endregion + } + + #region PreservingObjectReferencesAttribute + [JsonObject(IsReference = true)] + public class EmployeeReference + { + public string Name { get; set; } + public EmployeeReference Manager { get; set; } + } + #endregion + + #region CustomCreationConverterObject + public interface IPerson + { + string FirstName { get; set; } + string LastName { get; set; } + DateTime BirthDate { get; set; } + } + + public class Employee : IPerson + { + public string FirstName { get; set; } + public string LastName { get; set; } + public DateTime BirthDate { get; set; } + + public string Department { get; set; } + public string JobTitle { get; set; } + } + + public class PersonConverter : CustomCreationConverter + { + public override IPerson Create(Type objectType) + { + return new Employee(); + } + } + #endregion + + public void CustomCreationConverterExample() + { + string json = null; + + #region CustomCreationConverterExample + //[ + // { + // "FirstName": "Maurice", + // "LastName": "Moss", + // "BirthDate": "\/Date(252291661000)\/", + // "Department": "IT", + // "JobTitle": "Support" + // }, + // { + // "FirstName": "Jen", + // "LastName": "Barber", + // "BirthDate": "\/Date(258771661000)\/", + // "Department": "IT", + // "JobTitle": "Manager" + // } + //] + + List people = JsonConvert.DeserializeObject>(json, new PersonConverter()); + + IPerson person = people[0]; + + Console.WriteLine(person.GetType()); + // Newtonsoft.Json.Tests.Employee + + Console.WriteLine(person.FirstName); + // Maurice + + Employee employee = (Employee)person; + + Console.WriteLine(employee.JobTitle); + // Support + #endregion + } + + public void ContractResolver() + { + #region ContractResolver + Product product = new Product + { + ExpiryDate = new DateTime(2010, 12, 20, 18, 1, 0, DateTimeKind.Utc), + Name = "Widget", + Price = 9.99m, + Sizes = new[] { "Small", "Medium", "Large" } + }; + + string json = + JsonConvert.SerializeObject( + product, + Formatting.Indented, + new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() } + ); + + //{ + // "name": "Widget", + // "expiryDate": "\/Date(1292868060000)\/", + // "price": 9.99, + // "sizes": [ + // "Small", + // "Medium", + // "Large" + // ] + //} + #endregion + } + + public void SerializingCollectionsSerializing() + { + #region SerializingCollectionsSerializing + Product p1 = new Product + { + Name = "Product 1", + Price = 99.95m, + ExpiryDate = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc), + }; + Product p2 = new Product + { + Name = "Product 2", + Price = 12.50m, + ExpiryDate = new DateTime(2009, 7, 31, 0, 0, 0, DateTimeKind.Utc), + }; + + List products = new List(); + products.Add(p1); + products.Add(p2); + + string json = JsonConvert.SerializeObject(products, Formatting.Indented); + //[ + // { + // "Name": "Product 1", + // "ExpiryDate": "\/Date(978048000000)\/", + // "Price": 99.95, + // "Sizes": null + // }, + // { + // "Name": "Product 2", + // "ExpiryDate": "\/Date(1248998400000)\/", + // "Price": 12.50, + // "Sizes": null + // } + //] + #endregion + } + + public void SerializingCollectionsDeserializing() + { + #region SerializingCollectionsDeserializing + string json = @"[ + { + 'Name': 'Product 1', + 'ExpiryDate': '\/Date(978048000000)\/', + 'Price': 99.95, + 'Sizes': null + }, + { + 'Name': 'Product 2', + 'ExpiryDate': '\/Date(1248998400000)\/', + 'Price': 12.50, + 'Sizes': null + } + ]"; + + List products = JsonConvert.DeserializeObject>(json); + + Console.WriteLine(products.Count); + // 2 + + Product p1 = products[0]; + + Console.WriteLine(p1.Name); + // Product 1 + #endregion + } + + public void SerializingCollectionsDeserializingDictionaries() + { + #region SerializingCollectionsDeserializingDictionaries + string json = @"{""key1"":""value1"",""key2"":""value2""}"; + + Dictionary values = JsonConvert.DeserializeObject>(json); + + Console.WriteLine(values.Count); + // 2 + + Console.WriteLine(values["key1"]); + // value1 + #endregion + } + + #region SerializingDatesInJson + public class LogEntry + { + public string Details { get; set; } + public DateTime LogDate { get; set; } + } + + public void WriteJsonDates() + { + LogEntry entry = new LogEntry + { + LogDate = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc), + Details = "Application started." + }; + + // default as of Json.NET 4.5 + string isoJson = JsonConvert.SerializeObject(entry); + // {"Details":"Application started.","LogDate":"2009-02-15T00:00:00Z"} + + JsonSerializerSettings microsoftDateFormatSettings = new JsonSerializerSettings + { + DateFormatHandling = DateFormatHandling.MicrosoftDateFormat + }; + string microsoftJson = JsonConvert.SerializeObject(entry, microsoftDateFormatSettings); + // {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"} + + string javascriptJson = JsonConvert.SerializeObject(entry, new JavaScriptDateTimeConverter()); + // {"Details":"Application started.","LogDate":new Date(1234656000000)} + } + #endregion + + #region ReducingSerializedJsonSizeOptOut + public class Car + { + // included in JSON + public string Model { get; set; } + public DateTime Year { get; set; } + public List Features { get; set; } + + // ignored + [JsonIgnore] + public DateTime LastModified { get; set; } + } + #endregion + + #region ReducingSerializedJsonSizeOptIn + [DataContract] + public class Computer + { + // included in JSON + [DataMember] + public string Name { get; set; } + [DataMember] + public decimal SalePrice { get; set; } + + // ignored + public string Manufacture { get; set; } + public int StockCount { get; set; } + public decimal WholeSalePrice { get; set; } + public DateTime NextShipmentDate { get; set; } + } + #endregion + + #region ReducingSerializedJsonSizeNullValueHandlingObject + public class Movie + { + public string Name { get; set; } + public string Description { get; set; } + public string Classification { get; set; } + public string Studio { get; set; } + public DateTime? ReleaseDate { get; set; } + public List ReleaseCountries { get; set; } + } + #endregion + + public void ReducingSerializedJsonSizeNullValueHandlingExample() + { + #region ReducingSerializedJsonSizeNullValueHandlingExample + Movie movie = new Movie(); + movie.Name = "Bad Boys III"; + movie.Description = "It's no Bad Boys"; + + string included = JsonConvert.SerializeObject(movie, + Formatting.Indented, + new JsonSerializerSettings { }); + + // { + // "Name": "Bad Boys III", + // "Description": "It's no Bad Boys", + // "Classification": null, + // "Studio": null, + // "ReleaseDate": null, + // "ReleaseCountries": null + // } + + string ignored = JsonConvert.SerializeObject(movie, + Formatting.Indented, + new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + + // { + // "Name": "Bad Boys III", + // "Description": "It's no Bad Boys" + // } + #endregion + } + + #region ReducingSerializedJsonSizeDefaultValueHandlingObject + public class Invoice + { + public string Company { get; set; } + public decimal Amount { get; set; } + + // false is default value of bool + public bool Paid { get; set; } + // null is default value of nullable + public DateTime? PaidDate { get; set; } + + // customize default values + [DefaultValue(30)] + public int FollowUpDays { get; set; } + [DefaultValue("")] + public string FollowUpEmailAddress { get; set; } + } + #endregion + + public void ReducingSerializedJsonSizeDefaultValueHandlingExample() + { + #region ReducingSerializedJsonSizeDefaultValueHandlingExample + Invoice invoice = new Invoice + { + Company = "Acme Ltd.", + Amount = 50.0m, + Paid = false, + FollowUpDays = 30, + FollowUpEmailAddress = string.Empty, + PaidDate = null + }; + + string included = JsonConvert.SerializeObject(invoice, + Formatting.Indented, + new JsonSerializerSettings { }); + + // { + // "Company": "Acme Ltd.", + // "Amount": 50.0, + // "Paid": false, + // "PaidDate": null, + // "FollowUpDays": 30, + // "FollowUpEmailAddress": "" + // } + + string ignored = JsonConvert.SerializeObject(invoice, + Formatting.Indented, + new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); + + // { + // "Company": "Acme Ltd.", + // "Amount": 50.0 + // } + #endregion + } + + #region ReducingSerializedJsonSizeContractResolverObject + public class DynamicContractResolver : DefaultContractResolver + { + private readonly char _startingWithChar; + public DynamicContractResolver(char startingWithChar) + { + _startingWithChar = startingWithChar; + } + + protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) + { + IList properties = base.CreateProperties(type, memberSerialization); + + // only serializer properties that start with the specified character + properties = + properties.Where(p => p.PropertyName.StartsWith(_startingWithChar.ToString())).ToList(); + + return properties; + } + } + + public class Book + { + public string BookName { get; set; } + public decimal BookPrice { get; set; } + public string AuthorName { get; set; } + public int AuthorAge { get; set; } + public string AuthorCountry { get; set; } + } + #endregion + + public void ReducingSerializedJsonSizeContractResolverExample() + { + #region ReducingSerializedJsonSizeContractResolverExample + Book book = new Book + { + BookName = "The Gathering Storm", + BookPrice = 16.19m, + AuthorName = "Brandon Sanderson", + AuthorAge = 34, + AuthorCountry = "United States of America" + }; + + string startingWithA = JsonConvert.SerializeObject(book, Formatting.Indented, + new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('A') }); + + // { + // "AuthorName": "Brandon Sanderson", + // "AuthorAge": 34, + // "AuthorCountry": "United States of America" + // } + + string startingWithB = JsonConvert.SerializeObject(book, Formatting.Indented, + new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('B') }); + + // { + // "BookName": "The Gathering Storm", + // "BookPrice": 16.19 + // } + #endregion + } + + #region SerializingPartialJsonFragmentsObject + public class SearchResult + { + public string Title { get; set; } + public string Content { get; set; } + public string Url { get; set; } + } + #endregion + + public void SerializingPartialJsonFragmentsExample() + { + #region SerializingPartialJsonFragmentsExample + string googleSearchText = @"{ + 'responseData': { + 'results': [ + { + 'GsearchResultClass': 'GwebSearch', + 'unescapedUrl': 'http://en.wikipedia.org/wiki/Paris_Hilton', + 'url': 'http://en.wikipedia.org/wiki/Paris_Hilton', + 'visibleUrl': 'en.wikipedia.org', + 'cacheUrl': 'http://www.google.com/search?q=cache:TwrPfhd22hYJ:en.wikipedia.org', + 'title': 'Paris Hilton - Wikipedia, the free encyclopedia', + 'titleNoFormatting': 'Paris Hilton - Wikipedia, the free encyclopedia', + 'content': '[1] In 2006, she released her debut album...' + }, + { + 'GsearchResultClass': 'GwebSearch', + 'unescapedUrl': 'http://www.imdb.com/name/nm0385296/', + 'url': 'http://www.imdb.com/name/nm0385296/', + 'visibleUrl': 'www.imdb.com', + 'cacheUrl': 'http://www.google.com/search?q=cache:1i34KkqnsooJ:www.imdb.com', + 'title': 'Paris Hilton', + 'titleNoFormatting': 'Paris Hilton', + 'content': 'Self: Zoolander. Socialite Paris Hilton...' + } + ], + 'cursor': { + 'pages': [ + { + 'start': '0', + 'label': 1 + }, + { + 'start': '4', + 'label': 2 + }, + { + 'start': '8', + 'label': 3 + }, + { + 'start': '12', + 'label': 4 + } + ], + 'estimatedResultCount': '59600000', + 'currentPageIndex': 0, + 'moreResultsUrl': 'http://www.google.com/search?oe=utf8&ie=utf8...' + } + }, + 'responseDetails': null, + 'responseStatus': 200 + }"; + + JObject googleSearch = JObject.Parse(googleSearchText); + + // get JSON result objects into a list + IList results = googleSearch["responseData"]["results"].Children().ToList(); + + // serialize JSON results into .NET objects + IList searchResults = new List(); + foreach (JToken result in results) + { + SearchResult searchResult = JsonConvert.DeserializeObject(result.ToString()); + searchResults.Add(searchResult); + } + + // Title = Paris Hilton - Wikipedia, the free encyclopedia + // Content = [1] In 2006, she released her debut album... + // Url = http://en.wikipedia.org/wiki/Paris_Hilton + + // Title = Paris Hilton + // Content = Self: Zoolander. Socialite Paris Hilton... + // Url = http://www.imdb.com/name/nm0385296/ + #endregion + } + } +} +#endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs index ce3d7662..c8b7eb2a 100644 --- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs @@ -72,5 +72,5 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("4.5.0.0")] #if !PocketPC -[assembly: AssemblyFileVersion("4.5.7.15121")] +[assembly: AssemblyFileVersion("4.5.7.15122")] #endif diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs index 2c8177c2..963a32a8 100644 --- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs @@ -90,7 +90,7 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("4.5.0.0")] #if !PocketPC -[assembly: AssemblyFileVersion("4.5.7.15121")] +[assembly: AssemblyFileVersion("4.5.7.15122")] #endif [assembly: CLSCompliant(true)]