diff --git a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs index f3cc600d..3f386471 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs @@ -1904,7 +1904,7 @@ namespace Newtonsoft.Json.Tests.Converters } #if !NET20 - class NullableXml + public class NullableXml { public string Name; public XElement notNull; diff --git a/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs index f37a87c1..4df563d6 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs @@ -30,6 +30,7 @@ using System.ComponentModel; #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) using System.Numerics; #endif +using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Tests.TestObjects; #if !NETFX_CORE using NUnit.Framework; @@ -1936,28 +1937,57 @@ Parameter name: arrayIndex", Assert.IsFalse(a.TryGetValue(null, StringComparison.Ordinal, out v)); } - [Test] - public void sdfsdf() + public class FooJsonConverter : JsonConverter { - string json = @" + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var token = JToken.FromObject(value, new JsonSerializer + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }); + if (token.Type == JTokenType.Object) + { + var o = (JObject)token; + o.AddFirst(new JProperty("foo", "bar")); + o.WriteTo(writer); + } + else + token.WriteTo(writer); + } + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + throw new NotSupportedException("This custom converter only supportes serialization and not deserialization."); + } -{ - ""resultCount"":1, - ""results"": [ -{""kind"":""software"", ""features"":[], ""supportedDevices"":[""all""], ""isGameCenterEnabled"":false, -""screenshotUrls"":[""http://a1483.phobos.apple.com/us/r1000/080/Purple/v4/97/93/25/9793257e-1508-631c-c867-7075fa4fd55a/mzl.vdfbnbtr.png"", ""http://a1052.phobos.apple.com/us/r1000/087/Purple/v4/8c/63/ec/8c63ecc0-4e1b-e8e5-d936-ac2ab3a5a09b/mzl.tcjeyxaz.png"", ""http://a955.phobos.apple.com/us/r1000/068/Purple/v4/b8/0f/3c/b80f3c4a-ef67-7c09-e7e0-71dd016b24eb/mzl.ytmcfche.png"", ""http://a139.phobos.apple.com/us/r1000/073/Purple/v4/85/22/78/852278c3-4c4f-1dd4-70a1-072722e233b6/mzl.lguhuzlo.png"", ""http://a1136.phobos.apple.com/us/r1000/091/Purple/v4/c7/25/52/c725526f-63d3-bb77-7cad-fce3a1725c1e/mzl.rrftrkgt.png""], ""ipadScreenshotUrls"":[], ""artworkUrl60"":""http://a1115.phobos.apple.com/us/r1000/119/Purple/v4/44/f8/a6/44f8a649-2a7f-05cb-bed1-9288f08f5e74/Icon.png"", ""artworkUrl512"":""http://a380.phobos.apple.com/us/r1000/062/Purple/v4/47/6e/ea/476eea43-10dd-17ae-e972-303e8008eac1/mzl.muprlqbf.png"", ""artistViewUrl"":""https://itunes.apple.com/us/artist/yellowpages.com-llc/id281970042?uo=4"", ""artistId"":281970042, ""artistName"":""YELLOWPAGES.COM LLC"", ""price"":0.00, ""version"":""3.9"", -""description"":""Find what\u2019s around you in a flash! Whether you\u2019re looking for a great place to eat or to find cheap gas on the way, the YP app connects you with local businesses, deals and events to help you get things done.\n\n\u2022 Search over 18 million businesses by typing, speaking, or browsing popular categories including movie theaters, hotels, mechanics, dentists, and more.\n\u2022 Add personalized shortcuts for instant access to nearby businesses, deals, gas prices and events.\n\u2022 Craving a specific food? We'll look through over 300,000 menus to figure out who's got what you want.\n\u2022 Find the \u201cbest\u201d gas prices near you with our unique visual gas price search.\n\u2022 Save with thousands of local coupons and deals from businesses near you.*\n\u2022 Get important information before heading out including:\n - Ratings and reviews\n - Photos \u2013 plus upload photos to your favorite businesses!\n - Restaurant and service menus\n - Movie showtimes\n - Hours of operation\n - Phone numbers\n - Maps and directions \n\nWhatever you need\u2026 Wherever you are\u2026 the YP app covers you locally. What are you waiting for? Try it now! \n\n\n\n* Some restrictions may apply. Please call first to confirm the business will accept this coupon. Not all businesses accept mobile coupons."", ""currency"":""USD"", ""genres"":[""Travel"", ""Navigation""], ""genreIds"":[""6003"", ""6010""], ""releaseDate"":""2008-07-11T07:00:00Z"", ""sellerName"":""Yellowpages.com"", ""bundleId"":""com.yellowpages.ypmobile"", ""trackId"":284806204, ""trackName"":""YP Local Search & Gas Prices"", ""primaryGenreName"":""Travel"", ""primaryGenreId"":6003, -""releaseNotes"":""\u2022 Support for full screen display on iPhone 5\n\u2022 Location Aware Autosuggest \u2013 based on your location, we'll suggest nearby businesses as you type to make searching faster\n\u2022 Crash and bug fixes to make the app more stable"", ""formattedPrice"":""Free"", ""wrapperType"":""software"", ""trackCensoredName"":""YP Local Search & Gas Prices"", ""languageCodesISO2A"":[""EN""], ""fileSizeBytes"":""8728406"", ""sellerUrl"":""http://www.yellowpages.com/products/ypmobile"", ""contentAdvisoryRating"":""4+"", ""averageUserRatingForCurrentVersion"":4.5, ""userRatingCountForCurrentVersion"":168, ""artworkUrl100"":""http://a380.phobos.apple.com/us/r1000/062/Purple/v4/47/6e/ea/476eea43-10dd-17ae-e972-303e8008eac1/mzl.muprlqbf.png"", ""trackViewUrl"":""https://itunes.apple.com/us/app/yp-local-search-gas-prices/id284806204?mt=8&uo=4"", ""trackContentRating"":""4+"", ""averageUserRating"":3.0, ""userRatingCount"":55022}] -} + public override bool CanRead + { + get { return false; } + } -"; + public override bool CanConvert(Type objectType) + { + return true; + } + } - JObject o = JObject.Parse(json); + [Test] + public void FromObjectInsideConverterWithCustomSerializer() + { + var p = new Person + { + Name = "Daniel Wertheim", + }; - string s = (string)o["results"][0]["description"]; + var settings = new JsonSerializerSettings + { + Converters = new List { new FooJsonConverter() }, + ContractResolver = new CamelCasePropertyNamesContractResolver() + }; - Assert.AreEqual("Find what’s around you in a flash! Whether you’re looking for a great place to eat or to find cheap gas on the way, the YP app connects you with local businesses, deals and events to help you get things done.\n\n• Search over 18 million businesses by typing, speaking, or browsing popular categories including movie theaters, hotels, mechanics, dentists, and more.\n• Add personalized shortcuts for instant access to nearby businesses, deals, gas prices and events.\n• Craving a specific food? We'll look through over 300,000 menus to figure out who's got what you want.\n• Find the “best” gas prices near you with our unique visual gas price search.\n• Save with thousands of local coupons and deals from businesses near you.*\n• Get important information before heading out including:\n - Ratings and reviews\n - Photos – plus upload photos to your favorite businesses!\n - Restaurant and service menus\n - Movie showtimes\n - Hours of operation\n - Phone numbers\n - Maps and directions \n\nWhatever you need… Wherever you are… the YP app covers you locally. What are you waiting for? Try it now! \n\n\n\n* Some restrictions may apply. Please call first to confirm the business will accept this coupon. Not all businesses accept mobile coupons.", s); + var json = JsonConvert.SerializeObject(p, settings); + + Assert.AreEqual(@"{""foo"":""bar"",""name"":""Daniel Wertheim"",""birthDate"":""0001-01-01T00:00:00"",""lastModified"":""0001-01-01T00:00:00""}", json); } } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs index dd69bf2e..d30c4b08 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs @@ -575,9 +575,52 @@ namespace Newtonsoft.Json.Tests.Linq public void GetTypeCode() { IConvertible v = new JValue(new Guid("0B5D4F85-E94C-4143-94C8-35F2AAEBB100")); - Assert.AreEqual(TypeCode.Object, v.GetTypeCode()); + + v = new JValue(new Uri("http://www.google.com")); + Assert.AreEqual(TypeCode.Object, v.GetTypeCode()); + +#if !(NET20 || NET35 || SILVERLIGHT) + v = new JValue(new BigInteger(3)); + Assert.AreEqual(TypeCode.Object, v.GetTypeCode()); +#endif + } + + [Test] + public void ToType() + { + IConvertible v = new JValue(9.0m); + + int i = (int)v.ToType(typeof (int), CultureInfo.InvariantCulture); + Assert.AreEqual(9, i); + + BigInteger bi = (BigInteger)v.ToType(typeof(BigInteger), CultureInfo.InvariantCulture); + Assert.AreEqual(new BigInteger(9), bi); } #endif + + [Test] + public void ToStringFormat() + { + JValue v = new JValue(new DateTime(2013, 02, 01, 01, 02, 03, 04)); + + Assert.AreEqual("2013", v.ToString("yyyy")); + } + + [Test] + public void ToStringNewTypes() + { + JArray a = new JArray( + new JValue(new DateTimeOffset(2013, 02, 01, 01, 02, 03, 04, TimeSpan.FromHours(1))), + new JValue(new BigInteger(5)), + new JValue(1.1f) + ); + + Assert.AreEqual(@"[ + ""2013-02-01T01:02:03.004+01:00"", + 5, + 1.1 +]", a.ToString()); + } } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net40.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net40.csproj index d9958b05..8d00be08 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net40.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net40.csproj @@ -507,9 +507,6 @@ true - - - {a9ae40ff-1a21-414a-9fe7-3be13644cc6d} diff --git a/Src/Newtonsoft.Json.Tests/Serialization/SerializationEventAttributeTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/SerializationEventAttributeTests.cs index 491993d6..21f430ad 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/SerializationEventAttributeTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/SerializationEventAttributeTests.cs @@ -318,8 +318,10 @@ namespace Newtonsoft.Json.Tests.Serialization // Verify contract is properly finding our callback var resolver = new DefaultContractResolver().ResolveContract(typeof(FooEvent)); +#pragma warning disable 612,618 Debug.Assert(resolver.OnError != null); Debug.Assert(resolver.OnError == typeof(FooEvent).GetMethod("OnError", BindingFlags.Instance | BindingFlags.NonPublic)); +#pragma warning restore 612,618 var serializer = JsonSerializer.Create(new JsonSerializerSettings { diff --git a/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs index 4ecdb7d3..4cc1be95 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs @@ -79,7 +79,7 @@ namespace Newtonsoft.Json.Tests.Serialization TypeNameHandling = TypeNameHandling.Auto }; var sw = new StringWriter(); - serializer.Serialize(new JsonTextWriter(sw) { Formatting = Formatting.Indented }, new WagePerson()); + serializer.Serialize(new JsonTextWriter(sw) { Formatting = Formatting.Indented }, new WagePerson(), typeof(Person)); var result = sw.ToString(); Assert.AreEqual(@"{ @@ -102,7 +102,7 @@ namespace Newtonsoft.Json.Tests.Serialization [Test] public void SerializeRootTypeNameAutoWithJsonConvert() { - string json = JsonConvert.SerializeObject(new WagePerson(), Formatting.Indented, new JsonSerializerSettings + string json = JsonConvert.SerializeObject(new WagePerson(), typeof(object), Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }); diff --git a/Src/Newtonsoft.Json/Bson/BsonWriter.cs b/Src/Newtonsoft.Json/Bson/BsonWriter.cs index bda5ea85..7259fd18 100644 --- a/Src/Newtonsoft.Json/Bson/BsonWriter.cs +++ b/Src/Newtonsoft.Json/Bson/BsonWriter.cs @@ -463,6 +463,10 @@ namespace Newtonsoft.Json.Bson } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) + /// + /// Writes a value. + /// + /// The value to write. public override void WriteValue(BigInteger value) { base.WriteValue(value); diff --git a/Src/Newtonsoft.Json/JsonConvert.cs b/Src/Newtonsoft.Json/JsonConvert.cs index ce718ad4..2b66c7d4 100644 --- a/Src/Newtonsoft.Json/JsonConvert.cs +++ b/Src/Newtonsoft.Json/JsonConvert.cs @@ -933,16 +933,6 @@ namespace Newtonsoft.Json return SerializeObject(value, Formatting.None, settings); } - public static string SerializeObject(T value, JsonSerializerSettings settings) - { - return SerializeObject(value, Formatting.None, settings); - } - - public static string SerializeObject(T value, Formatting formatting, JsonSerializerSettings settings) - { - return SerializeObjectInternal(value, formatting, settings, typeof (T)); - } - /// /// Serializes the specified object to a JSON string using a collection of . /// @@ -955,10 +945,25 @@ namespace Newtonsoft.Json /// public static string SerializeObject(object value, Formatting formatting, JsonSerializerSettings settings) { - return SerializeObjectInternal(value, formatting, settings, null); + return SerializeObject(value, null, formatting, settings); } - public static string SerializeObjectInternal(object value, Formatting formatting, JsonSerializerSettings settings, Type rootType) + /// + /// Serializes the specified object to a JSON string using a collection of . + /// + /// The object to serialize. + /// Indicates how the output is formatted. + /// The used to serialize the object. + /// If this is null, default serialization settings will be is used. + /// + /// The type of the value being serialized. + /// This parameter is used when is Auto to write out the type name if the type of the value does not match. + /// Specifing the type is optional. + /// + /// + /// A JSON string representation of the object. + /// + public static string SerializeObject(object value, Type type, Formatting formatting, JsonSerializerSettings settings) { JsonSerializer jsonSerializer = JsonSerializer.Create(settings); @@ -968,7 +973,7 @@ namespace Newtonsoft.Json { jsonWriter.Formatting = formatting; - jsonSerializer.Serialize(jsonWriter, value, rootType); + jsonSerializer.Serialize(jsonWriter, value, type); } return sw.ToString(); @@ -1080,6 +1085,21 @@ namespace Newtonsoft.Json return DeserializeObject(value); } + /// + /// Deserializes the JSON to the given anonymous type. + /// + /// + /// The anonymous type to deserialize to. This can't be specified + /// traditionally and must be infered from the anonymous type passed + /// as a parameter. + /// + /// The JSON to deserialize. + /// The anonymous type object. + /// + /// The used to deserialize the object. + /// If this is null, default serialization settings will be is used. + /// + /// The deserialized anonymous type from the JSON string. public static T DeserializeAnonymousType(string value, T anonymousTypeObject, JsonSerializerSettings settings) { return DeserializeObject(value, settings); diff --git a/Src/Newtonsoft.Json/JsonSerializer.cs b/Src/Newtonsoft.Json/JsonSerializer.cs index 9e661635..c4f6f2bd 100644 --- a/Src/Newtonsoft.Json/JsonSerializer.cs +++ b/Src/Newtonsoft.Json/JsonSerializer.cs @@ -632,14 +632,36 @@ namespace Newtonsoft.Json Serialize(new JsonTextWriter(textWriter), value); } - public void Serialize(JsonWriter jsonWriter, object value, Type rootType) + /// + /// Serializes the specified and writes the Json structure + /// to a Stream using the specified . + /// + /// The used to write the Json structure. + /// The to serialize. + /// + /// The type of the value being serialized. + /// This parameter is used when is Auto to write out the type name if the type of the value does not match. + /// Specifing the type is optional. + /// + public void Serialize(JsonWriter jsonWriter, object value, Type objectType) { - SerializeInternal(jsonWriter, value, rootType); + SerializeInternal(jsonWriter, value, objectType); } - public void Serialize(TextWriter textWriter, object value, Type rootType) + /// + /// Serializes the specified and writes the Json structure + /// to a Stream using the specified . + /// + /// The used to write the Json structure. + /// The to serialize. + /// + /// The type of the value being serialized. + /// This parameter is used when is Auto to write out the type name if the type of the value does not match. + /// Specifing the type is optional. + /// + public void Serialize(TextWriter textWriter, object value, Type objectType) { - Serialize(new JsonTextWriter(textWriter), value, rootType); + Serialize(new JsonTextWriter(textWriter), value, objectType); } /// @@ -653,12 +675,7 @@ namespace Newtonsoft.Json SerializeInternal(jsonWriter, value, null); } - public void Serialize(JsonWriter jsonWriter, object value) - { - SerializeInternal(jsonWriter, value, typeof(T)); - } - - internal virtual void SerializeInternal(JsonWriter jsonWriter, object value, Type rootType) + internal virtual void SerializeInternal(JsonWriter jsonWriter, object value, Type objectType) { ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter"); @@ -713,7 +730,7 @@ namespace Newtonsoft.Json } JsonSerializerInternalWriter serializerWriter = new JsonSerializerInternalWriter(this); - serializerWriter.Serialize(jsonWriter, value, rootType); + serializerWriter.Serialize(jsonWriter, value, objectType); // reset writer back to previous options if (previousFormatting != null) diff --git a/Src/Newtonsoft.Json/JsonTextWriter.cs b/Src/Newtonsoft.Json/JsonTextWriter.cs index 90d841f1..3ab5f32b 100644 --- a/Src/Newtonsoft.Json/JsonTextWriter.cs +++ b/Src/Newtonsoft.Json/JsonTextWriter.cs @@ -214,6 +214,11 @@ namespace Newtonsoft.Json _writer.Write(':'); } + /// + /// Writes the property name of a name/value pair on a JSON object. + /// + /// The name of the property. + /// A flag to indicate whether the text should be escaped when it is written as a JSON property name. public override void WritePropertyName(string name, bool escape) { InternalWritePropertyName(name); diff --git a/Src/Newtonsoft.Json/JsonWriter.cs b/Src/Newtonsoft.Json/JsonWriter.cs index 8da942f7..976db4c8 100644 --- a/Src/Newtonsoft.Json/JsonWriter.cs +++ b/Src/Newtonsoft.Json/JsonWriter.cs @@ -406,7 +406,7 @@ namespace Newtonsoft.Json } /// - /// Writes the property name of a name/value pair on a Json object. + /// Writes the property name of a name/value pair on a JSON object. /// /// The name of the property. public virtual void WritePropertyName(string name) @@ -414,6 +414,11 @@ namespace Newtonsoft.Json InternalWritePropertyName(name); } + /// + /// Writes the property name of a name/value pair on a JSON object. + /// + /// The name of the property. + /// A flag to indicate whether the text should be escaped when it is written as a JSON property name. public virtual void WritePropertyName(string name, bool escape) { WritePropertyName(name); diff --git a/Src/Newtonsoft.Json/Linq/JValue.cs b/Src/Newtonsoft.Json/Linq/JValue.cs index 06cd03f9..bd193600 100644 --- a/Src/Newtonsoft.Json/Linq/JValue.cs +++ b/Src/Newtonsoft.Json/Linq/JValue.cs @@ -931,7 +931,7 @@ namespace Newtonsoft.Json.Linq #endif #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) if (_value is BigInteger) - return TypeCode.Int64; + return TypeCode.Object; #endif return System.Type.GetTypeCode(_value.GetType()); diff --git a/Src/Newtonsoft.Json/Serialization/JsonContract.cs b/Src/Newtonsoft.Json/Serialization/JsonContract.cs index e6d47030..bdf91c15 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonContract.cs @@ -51,8 +51,19 @@ namespace Newtonsoft.Json.Serialization Linq } + /// + /// Handles serialization callback events. + /// + /// The object that raised the callback event. + /// The streaming context. public delegate void SerializationCallback(object o, StreamingContext context); + /// + /// Handles serialization error callback events. + /// + /// The object that raised the callback event. + /// The streaming context. + /// The error context. public delegate void SerializationErrorCallback(object o, StreamingContext context, ErrorContext errorContext); /// diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs index c8df2715..47c0855f 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs @@ -56,13 +56,13 @@ namespace Newtonsoft.Json.Serialization { } - public void Serialize(JsonWriter jsonWriter, object value, Type rootType) + public void Serialize(JsonWriter jsonWriter, object value, Type objectType) { if (jsonWriter == null) throw new ArgumentNullException("jsonWriter"); - if (rootType != null) - _rootContract = Serializer.ContractResolver.ResolveContract(rootType); + if (objectType != null) + _rootContract = Serializer.ContractResolver.ResolveContract(objectType); SerializeValue(jsonWriter, value, GetContractSafe(value), null, null, null); }