diff --git a/Src/Doc/SelectToken.html b/Src/Doc/SelectToken.html index cb013613..7b92a2ed 100644 --- a/Src/Doc/SelectToken.html +++ b/Src/Doc/SelectToken.html @@ -15,8 +15,18 @@

SelectToken provides a method to query LINQ to JSON using a single string path to a - desired JToken. SelectToken makes dynamic queries much easier because the entire + desired JToken. SelectToken makes dynamic queries + easy because the entire query is defined in a string.

+ +
+
+
+
string name = (string)o.SelectToken("Manufacturers[0].Name");
+ +
+
+

SelectToken

SelectToken is a method on JToken and takes a string path to a child token. @@ -25,7 +35,7 @@

The path is made up of property names and array indexes separated by periods. Array indexes can use either square or round brackets. Both - of the following are valid paths and are equivilent to each other: Manufacturers[0].Name + of the following are valid paths and are equivalent to each other: Manufacturers[0].Name and Manufacturers(0).Name.

diff --git a/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs b/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs index 83c7bfd0..bc3d323a 100644 --- a/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs @@ -350,5 +350,46 @@ namespace Newtonsoft.Json.Tests.Bson writer.WriteStartArray(); writer.WriteRawValue("fail"); } + + [Test] + public void Example() + { + Product p = new Product(); + p.ExpiryDate = DateTime.Parse("2009-04-05T14:45:00Z"); + p.Name = "Carlos' Spicy Wieners"; + p.Price = 9.95m; + p.Sizes = new[] { "Small", "Medium", "Large" }; + + MemoryStream ms = new MemoryStream(); + JsonSerializer serializer = new JsonSerializer(); + + // serialize product to BSON + BsonWriter writer = new BsonWriter(ms); + serializer.Serialize(writer, p); + + Console.WriteLine(BitConverter.ToString(ms.ToArray())); + // 7C-00-00-00-02-4E-61-6D-65-00-16-00-00-00-43-61-72-6C- + // 6F-73-27-20-53-70-69-63-79-20-57-69-65-6E-65-72-73-00- + // 09-45-78-70-69-72-79-44-61-74-65-00-E0-51-BD-76-20-01- + // 00-00-01-50-72-69-63-65-00-66-66-66-66-66-E6-23-40-04- + // 53-69-7A-65-73-00-2D-00-00-00-02-30-00-06-00-00-00-53- + // 6D-61-6C-6C-00-02-31-00-07-00-00-00-4D-65-64-69-75-6D- + // 00-02-32-00-06-00-00-00-4C-61-72-67-65-00-00-00 + + + ms.Seek(0, SeekOrigin.Begin); + + // deserialize product from BSON + BsonReader reader = new BsonReader(ms); + Product deserializedProduct = serializer.Deserialize(reader); + + Console.WriteLine(deserializedProduct.Name); + // Carlos' Spicy Wieners + + + Assert.AreEqual("Carlos' Spicy Wieners", deserializedProduct.Name); + Assert.AreEqual(9.95m, deserializedProduct.Price); + Assert.AreEqual(3, deserializedProduct.Sizes.Length); + } } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Converters/DataSetConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/DataSetConverterTests.cs index 6f4afaa1..9c4abf99 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/DataSetConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/DataSetConverterTests.cs @@ -67,36 +67,80 @@ namespace Newtonsoft.Json.Tests.Converters Assert.AreEqual(2, dt.Rows.Count); } + [Test] public void SerializeMultiTableDataSet() { DataSet ds = new DataSet(); - ds.Tables.Add(CreateDataTable("FirstTable")); - ds.Tables.Add(CreateDataTable("SecondTable")); + ds.Tables.Add(CreateDataTable("FirstTable", 2)); + ds.Tables.Add(CreateDataTable("SecondTable", 1)); string json = JsonConvert.SerializeObject(ds, Formatting.Indented, new IsoDateTimeConverter()); + // { + // "FirstTable": [ + // { + // "StringCol": "Item Name", + // "Int32Col": 1, + // "BooleanCol": true, + // "TimeSpanCol": "10.22:10:15.1000000", + // "DateTimeCol": "2000-12-29T00:00:00Z", + // "DecimalCol": 64.0021 + // }, + // { + // "StringCol": "Item Name", + // "Int32Col": 2, + // "BooleanCol": true, + // "TimeSpanCol": "10.22:10:15.1000000", + // "DateTimeCol": "2000-12-29T00:00:00Z", + // "DecimalCol": 64.0021 + // } + // ], + // "SecondTable": [ + // { + // "StringCol": "Item Name", + // "Int32Col": 1, + // "BooleanCol": true, + // "TimeSpanCol": "10.22:10:15.1000000", + // "DateTimeCol": "2000-12-29T00:00:00Z", + // "DecimalCol": 64.0021 + // } + // ] + // } + + DataSet deserializedDs = JsonConvert.DeserializeObject(json, new IsoDateTimeConverter()); Assert.AreEqual(@"{ ""FirstTable"": [ { ""StringCol"": ""Item Name"", - ""Int32Col"": 2147483647, + ""Int32Col"": 1, ""BooleanCol"": true, ""TimeSpanCol"": ""10.22:10:15.1000000"", - ""DateTimeCol"": ""2000-12-29T00:00:00"", + ""DateTimeCol"": ""2000-12-29T00:00:00Z"", + ""DecimalCol"": 64.0021 + }, + { + ""StringCol"": ""Item Name"", + ""Int32Col"": 2, + ""BooleanCol"": true, + ""TimeSpanCol"": ""10.22:10:15.1000000"", + ""DateTimeCol"": ""2000-12-29T00:00:00Z"", ""DecimalCol"": 64.0021 } ], ""SecondTable"": [ { ""StringCol"": ""Item Name"", - ""Int32Col"": 2147483647, + ""Int32Col"": 1, ""BooleanCol"": true, ""TimeSpanCol"": ""10.22:10:15.1000000"", - ""DateTimeCol"": ""2000-12-29T00:00:00"", + ""DateTimeCol"": ""2000-12-29T00:00:00Z"", ""DecimalCol"": 64.0021 } ] }", json); + + Assert.IsNotNull(deserializedDs); + } [Test] @@ -109,7 +153,7 @@ namespace Newtonsoft.Json.Tests.Converters ""Int32Col"": 2147483647, ""BooleanCol"": true, ""TimeSpanCol"": ""10.22:10:15.1000000"", - ""DateTimeCol"": ""2000-12-29T00:00:00"", + ""DateTimeCol"": ""2000-12-29T00:00:00Z"", ""DecimalCol"": 64.0021 } ], @@ -119,7 +163,7 @@ namespace Newtonsoft.Json.Tests.Converters ""Int32Col"": 2147483647, ""BooleanCol"": true, ""TimeSpanCol"": ""10.22:10:15.1000000"", - ""DateTimeCol"": ""2000-12-29T00:00:00"", + ""DateTimeCol"": ""2000-12-29T00:00:00Z"", ""DecimalCol"": 64.0021 } ] @@ -150,7 +194,7 @@ namespace Newtonsoft.Json.Tests.Converters Assert.AreEqual(1, ds.Tables[1].Rows.Count); } - private DataTable CreateDataTable(string dataTableName) + private DataTable CreateDataTable(string dataTableName, int rows) { // create a new DataTable. DataTable myTable = new DataTable(dataTableName); @@ -181,16 +225,18 @@ namespace Newtonsoft.Json.Tests.Converters colDecimal.DataType = typeof(decimal); myTable.Columns.Add(colDecimal); - // populate one row with values. - DataRow myNewRow = myTable.NewRow(); + for (int i = 1; i <= rows; i++) + { + DataRow myNewRow = myTable.NewRow(); - myNewRow["StringCol"] = "Item Name"; - myNewRow["Int32Col"] = 2147483647; - myNewRow["BooleanCol"] = true; - myNewRow["TimeSpanCol"] = new TimeSpan(10, 22, 10, 15, 100); - myNewRow["DateTimeCol"] = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc); - myNewRow["DecimalCol"] = 64.0021; - myTable.Rows.Add(myNewRow); + myNewRow["StringCol"] = "Item Name"; + myNewRow["Int32Col"] = i; + myNewRow["BooleanCol"] = true; + myNewRow["TimeSpanCol"] = new TimeSpan(10, 22, 10, 15, 100); + myNewRow["DateTimeCol"] = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc); + myNewRow["DecimalCol"] = 64.0021; + myTable.Rows.Add(myNewRow); + } return myTable; } diff --git a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs index 208efadd..e01f4994 100644 --- a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs +++ b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs @@ -260,7 +260,7 @@ namespace Newtonsoft.Json.Tests address.Entered = DateTime.Now.AddDays(-2); address.Address = "array 2 address"; test.Addresses.Add(address); - + BenchmarkSerializeMethod(SerializeMethod.JsonNet, test); BenchmarkSerializeMethod(SerializeMethod.JsonNetBinary, test); BenchmarkSerializeMethod(SerializeMethod.JavaScriptSerializer, test); diff --git a/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs b/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs index 765909f4..4953f99a 100644 --- a/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs +++ b/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs @@ -36,7 +36,7 @@ namespace Newtonsoft.Json.Tests [TestFixture] public abstract class TestFixtureBase { - [TestFixtureSetUp] + [SetUp] protected void TestSetup() { //CultureInfo turkey = CultureInfo.CreateSpecificCulture("tr"); diff --git a/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs b/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs index 5a967db5..2c4f7df8 100644 --- a/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs +++ b/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs @@ -23,11 +23,6 @@ // OTHER DEALINGS IN THE SOFTWARE. #endregion -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - namespace Newtonsoft.Json.Bson { internal enum BsonBinaryType : byte diff --git a/Src/Newtonsoft.Json/Bson/BsonReader.cs b/Src/Newtonsoft.Json/Bson/BsonReader.cs index b0d6f7c0..da3525df 100644 --- a/Src/Newtonsoft.Json/Bson/BsonReader.cs +++ b/Src/Newtonsoft.Json/Bson/BsonReader.cs @@ -26,7 +26,6 @@ using System; using System.Collections.Generic; using System.Globalization; -using System.Linq; using System.Text; using System.IO; using Newtonsoft.Json.Utilities; diff --git a/Src/Newtonsoft.Json/Bson/BsonType.cs b/Src/Newtonsoft.Json/Bson/BsonType.cs index 3c98d588..7b6def29 100644 --- a/Src/Newtonsoft.Json/Bson/BsonType.cs +++ b/Src/Newtonsoft.Json/Bson/BsonType.cs @@ -23,11 +23,6 @@ // OTHER DEALINGS IN THE SOFTWARE. #endregion -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - namespace Newtonsoft.Json.Bson { internal enum BsonType : sbyte diff --git a/Src/Newtonsoft.Json/Bson/BsonWriter.cs b/Src/Newtonsoft.Json/Bson/BsonWriter.cs index aa15cb18..575c5c16 100644 --- a/Src/Newtonsoft.Json/Bson/BsonWriter.cs +++ b/Src/Newtonsoft.Json/Bson/BsonWriter.cs @@ -117,7 +117,7 @@ namespace Newtonsoft.Json.Bson _writer.Write(data); break; default: - throw new ArgumentOutOfRangeException("Type", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type)); + throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type)); } } @@ -158,7 +158,7 @@ namespace Newtonsoft.Json.Bson case JTokenType.Bytes: return BsonType.Binary; default: - throw new ArgumentOutOfRangeException("Type", "Unexpected token when resolving JSON type to BSON type: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type)); + throw new ArgumentOutOfRangeException("t", "Unexpected token when resolving JSON type to BSON type: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type)); } } @@ -231,7 +231,7 @@ namespace Newtonsoft.Json.Bson byte[] data = (byte[]) t; return 4 + 1 + data.Length; default: - throw new ArgumentOutOfRangeException("Type", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type)); + throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type)); } } @@ -249,21 +249,37 @@ namespace Newtonsoft.Json.Bson } } + /// + /// Writes out a comment /*...*/ containing the specified text. + /// + /// Text to place inside the comment. public override void WriteComment(string text) { throw new JsonWriterException("Cannot write JSON comment as BSON."); } + /// + /// Writes the start of a constructor with the given name. + /// + /// The name of the constructor. public override void WriteStartConstructor(string name) { throw new JsonWriterException("Cannot write JSON constructor as BSON."); } + /// + /// Writes raw JSON. + /// + /// The raw JSON to write. public override void WriteRaw(string json) { throw new JsonWriterException("Cannot write raw JSON as BSON."); } + /// + /// Writes raw JSON where a value is expected and updates the writer's state. + /// + /// The raw JSON to write. public override void WriteRawValue(string json) { throw new JsonWriterException("Cannot write raw JSON as BSON."); diff --git a/Src/Newtonsoft.Json/Converters/BinaryConverter.cs b/Src/Newtonsoft.Json/Converters/BinaryConverter.cs index 2a344239..6b039448 100644 --- a/Src/Newtonsoft.Json/Converters/BinaryConverter.cs +++ b/Src/Newtonsoft.Json/Converters/BinaryConverter.cs @@ -24,12 +24,9 @@ #endregion using System; -using System.Collections.Generic; #if !SILVERLIGHT using System.Data.SqlTypes; #endif -using System.Linq; -using System.Text; using System.Globalization; using Newtonsoft.Json.Utilities; @@ -135,16 +132,12 @@ namespace Newtonsoft.Json.Converters /// public override bool CanConvert(Type objectType) { - Type t = (ReflectionUtils.IsNullableType(objectType)) - ? Nullable.GetUnderlyingType(objectType) - : objectType; - #if !SILVERLIGHT && !PocketPC && !NET20 - if (t.AssignableToTypeName(BinaryTypeName)) + if (objectType.AssignableToTypeName(BinaryTypeName)) return true; #endif #if !SILVERLIGHT - if (t == typeof(SqlBinary)) + if (objectType == typeof(SqlBinary) || objectType == typeof(SqlBinary?)) return true; #endif return false; diff --git a/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs b/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs index 873a2536..d5f6441e 100644 --- a/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs +++ b/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs @@ -24,9 +24,6 @@ #endregion using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Newtonsoft.Json.Converters { diff --git a/Src/Newtonsoft.Json/Converters/DataSetConverter.cs b/Src/Newtonsoft.Json/Converters/DataSetConverter.cs index 89b4833c..24088cc2 100644 --- a/Src/Newtonsoft.Json/Converters/DataSetConverter.cs +++ b/Src/Newtonsoft.Json/Converters/DataSetConverter.cs @@ -25,10 +25,7 @@ #if !SILVERLIGHT using System; -using System.Collections.Generic; using System.Data; -using System.Linq; -using System.Text; namespace Newtonsoft.Json.Converters { diff --git a/Src/Newtonsoft.Json/Converters/DataTableConverter.cs b/Src/Newtonsoft.Json/Converters/DataTableConverter.cs index 7c04c55a..06117ac3 100644 --- a/Src/Newtonsoft.Json/Converters/DataTableConverter.cs +++ b/Src/Newtonsoft.Json/Converters/DataTableConverter.cs @@ -25,9 +25,6 @@ #if !SILVERLIGHT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Data; namespace Newtonsoft.Json.Converters diff --git a/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs b/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs new file mode 100644 index 00000000..8c2f0681 --- /dev/null +++ b/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Newtonsoft.Json.Converters +{ + /// + /// Provides a base class for converting a to and from JSON. + /// + public abstract class DateTimeConverterBase : JsonConverter + { + /// + /// Determines whether this instance can convert the specified object type. + /// + /// Type of the object. + /// + /// true if this instance can convert the specified object type; otherwise, false. + /// + public override bool CanConvert(Type objectType) + { + if (objectType == typeof(DateTime) || objectType == typeof(DateTime?)) + return true; +#if !PocketPC && !NET20 + if (objectType == typeof(DateTimeOffset) || objectType == typeof(DateTimeOffset?)) + return true; +#endif + + return false; + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs b/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs index 31064713..e47e5c11 100644 --- a/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs +++ b/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs @@ -25,13 +25,9 @@ #if !PocketPC && !SILVERLIGHT && !NET20 using System; -using System.Data; -using System.Reflection; using Newtonsoft.Json.Serialization; using System.Globalization; using Newtonsoft.Json.Utilities; -using System.Linq; -using System.Reflection.Emit; namespace Newtonsoft.Json.Converters { diff --git a/Src/Newtonsoft.Json/Converters/HtmlColorConverter.cs b/Src/Newtonsoft.Json/Converters/HtmlColorConverter.cs index c82875eb..fdde9c3b 100644 --- a/Src/Newtonsoft.Json/Converters/HtmlColorConverter.cs +++ b/Src/Newtonsoft.Json/Converters/HtmlColorConverter.cs @@ -25,8 +25,6 @@ #if !SILVERLIGHT && !PocketPC using System; -using System.Collections.Generic; -using System.Text; using System.Drawing; namespace Newtonsoft.Json.Converters diff --git a/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs b/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs index 0e37a87e..5150c441 100644 --- a/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs +++ b/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Globalization; using Newtonsoft.Json.Utilities; @@ -10,7 +7,7 @@ namespace Newtonsoft.Json.Converters /// /// Converts a to and from the ISO 8601 date format (e.g. 2008-04-12T12:53Z). /// - public class IsoDateTimeConverter : JsonConverter + public class IsoDateTimeConverter : DateTimeConverterBase { private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; @@ -132,28 +129,5 @@ namespace Newtonsoft.Json.Converters else return DateTime.Parse(dateText, Culture, _dateTimeStyles); } - - /// - /// Determines whether this instance can convert the specified object type. - /// - /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// - public override bool CanConvert(Type objectType) - { - Type t = (ReflectionUtils.IsNullableType(objectType)) - ? Nullable.GetUnderlyingType(objectType) - : objectType; - - if (t == typeof(DateTime)) - return true; -#if !PocketPC && !NET20 - if (t == typeof(DateTimeOffset)) - return true; -#endif - - return false; - } } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs b/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs index be043dde..130f63e6 100644 --- a/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs +++ b/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs @@ -7,7 +7,7 @@ namespace Newtonsoft.Json.Converters /// /// Converts a to and from a JavaScript date constructor (e.g. new Date(52231943)). /// - public class JavaScriptDateTimeConverter : JsonConverter + public class JavaScriptDateTimeConverter : DateTimeConverterBase { /// /// Writes the JSON representation of the object. @@ -53,8 +53,8 @@ namespace Newtonsoft.Json.Converters public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer) { Type t = (ReflectionUtils.IsNullableType(objectType)) - ? Nullable.GetUnderlyingType(objectType) - : objectType; + ? Nullable.GetUnderlyingType(objectType) + : objectType; if (reader.TokenType == JsonToken.Null) { @@ -88,28 +88,5 @@ namespace Newtonsoft.Json.Converters return d; } - - /// - /// Determines whether this instance can convert the specified object type. - /// - /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// - public override bool CanConvert(Type objectType) - { - Type t = (ReflectionUtils.IsNullableType(objectType)) - ? Nullable.GetUnderlyingType(objectType) - : objectType; - - if (t == typeof(DateTime)) - return true; -#if !PocketPC && !NET20 - if (t == typeof(DateTimeOffset)) - return true; -#endif - - return false; - } } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs index 13361658..7d63d7ea 100644 --- a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs +++ b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs @@ -26,7 +26,6 @@ #if !SILVERLIGHT using System; using System.Collections.Generic; -using System.Text; using System.Xml; using Newtonsoft.Json.Utilities; using System.Linq; @@ -146,7 +145,7 @@ namespace Newtonsoft.Json.Converters else { string elementNames = nodeNameGroup.Key; - writer.WritePropertyName(nodeNameGroup.Key); + writer.WritePropertyName(elementNames); writer.WriteStartArray(); for (int i = 0; i < groupedNodes.Count; i++) diff --git a/Src/Newtonsoft.Json/JsonSerializer.cs b/Src/Newtonsoft.Json/JsonSerializer.cs index e8cc5994..0403b057 100644 --- a/Src/Newtonsoft.Json/JsonSerializer.cs +++ b/Src/Newtonsoft.Json/JsonSerializer.cs @@ -54,18 +54,6 @@ namespace Newtonsoft.Json private IReferenceResolver _referenceResolver; private SerializationBinder _binder; - private static readonly IList BuiltInConverters = new List - { -#if !PocketPC && !SILVERLIGHT && !NET20 - new EntityKeyMemberConverter(), -#endif - new BinaryConverter(), -#if !SILVERLIGHT - new DataSetConverter(), - new DataTableConverter() -#endif - }; - /// /// Occurs when the errors during serialization and deserialization. /// @@ -368,6 +356,18 @@ namespace Newtonsoft.Json return Deserialize(new JsonTextReader(reader), objectType); } + /// + /// Deserializes the Json structure contained by the specified + /// into an instance of the specified type. + /// + /// The containing the object. + /// The type of the object to deserialize. + /// The instance of being deserialized. + public T Deserialize(JsonReader reader) + { + return (T)Deserialize(reader, typeof(T)); + } + /// /// Deserializes the Json structure contained by the specified /// into an instance of the specified type. @@ -423,7 +423,9 @@ namespace Newtonsoft.Json if (objectType == null) throw new ArgumentNullException("objectType"); - converter = JsonTypeReflector.GetJsonConverter(objectType, objectType); + JsonContract contract = ContractResolver.ResolveContract(objectType); + converter = contract.Converter; + return (converter != null); } @@ -431,8 +433,6 @@ namespace Newtonsoft.Json { if (HasMatchingConverter(_converters, type, out matchingConverter)) return true; - if (HasMatchingConverter(BuiltInConverters, type, out matchingConverter)) - return true; return false; } diff --git a/Src/Newtonsoft.Json/Linq/JTokenWriter.cs b/Src/Newtonsoft.Json/Linq/JTokenWriter.cs index 35f56be8..e5cee0cf 100644 --- a/Src/Newtonsoft.Json/Linq/JTokenWriter.cs +++ b/Src/Newtonsoft.Json/Linq/JTokenWriter.cs @@ -183,6 +183,10 @@ namespace Newtonsoft.Json.Linq AddValue(JValue.CreateRaw(json), JsonToken.Raw); } + /// + /// Writes out a comment /*...*/ containing the specified text. + /// + /// Text to place inside the comment. public override void WriteComment(string text) { base.WriteComment(text); diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj index 3fedf28c..75491644 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj @@ -62,6 +62,7 @@ + diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj index 325ddaca..d976e8e7 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj @@ -82,6 +82,7 @@ + diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj index 0de29b41..0b8e841c 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj @@ -59,6 +59,7 @@ + diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj index f81607fa..faf940f7 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj @@ -85,6 +85,7 @@ + diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs index 18473197..ec5f0aaf 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs @@ -31,6 +31,7 @@ using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.Serialization; +using Newtonsoft.Json.Converters; using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Serialization @@ -41,6 +42,17 @@ namespace Newtonsoft.Json.Serialization public class DefaultContractResolver : IContractResolver { internal static readonly IContractResolver Instance = new DefaultContractResolver(); + private static readonly IList BuiltInConverters = new List + { +#if !PocketPC && !SILVERLIGHT && !NET20 + new EntityKeyMemberConverter(), +#endif + new BinaryConverter(), +#if !SILVERLIGHT + new DataSetConverter(), + new DataTableConverter() +#endif + }; private readonly ThreadSafeStore _typeContractCache; @@ -154,6 +166,23 @@ namespace Newtonsoft.Json.Serialization return null; } + /// + /// Resolves the default for the contract. + /// + /// Type of the object. + /// + protected virtual JsonConverter ResolveContractConverter(Type objectType) + { + // check for an attribute first + JsonConverter converter = JsonTypeReflector.GetJsonConverter(objectType, objectType); + if (converter != null) + return converter; + + // then see whether object is compadible with any of the built in converters + JsonSerializer.HasMatchingConverter(BuiltInConverters, objectType, out converter); + return converter; + } + private void InitializeContract(JsonContract contract) { JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(contract.UnderlyingType); @@ -171,6 +200,8 @@ namespace Newtonsoft.Json.Serialization } #endif + contract.Converter = ResolveContractConverter(contract.UnderlyingType); + if (ReflectionUtils.HasDefaultConstructor(contract.CreatedType, true) || contract.CreatedType.IsValueType) { @@ -350,6 +381,9 @@ namespace Newtonsoft.Json.Serialization #else property.ValueProvider = new ReflectionValueProvider(member); #endif + + // resolve converter for property + // the class type might have a converter but the property converter takes presidence property.Converter = JsonTypeReflector.GetJsonConverter(member, property.PropertyType); #if !PocketPC && !NET20 diff --git a/Src/Newtonsoft.Json/Serialization/JsonContract.cs b/Src/Newtonsoft.Json/Serialization/JsonContract.cs index 4b78a7ca..16399ff0 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonContract.cs @@ -53,6 +53,12 @@ namespace Newtonsoft.Json.Serialization /// Whether this type contract is serialized as a reference. public bool? IsReference { get; set; } + /// + /// Gets or sets the default for this contract. + /// + /// The converter. + public JsonConverter Converter { get; set; } + private static readonly StreamingContext SerializationStreamingContextParameter = new StreamingContext(); private static readonly object[] SerializationEventParameterValues = new object[] { SerializationStreamingContextParameter }; diff --git a/Src/Newtonsoft.Json/Serialization/JsonProperty.cs b/Src/Newtonsoft.Json/Serialization/JsonProperty.cs index 43ee5079..6604c644 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonProperty.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonProperty.cs @@ -51,7 +51,8 @@ namespace Newtonsoft.Json.Serialization public Type PropertyType { get; set; } /// - /// Gets or sets the converter. + /// Gets or sets the for the property. + /// If set this converter takes presidence over the contract converter for the property type. /// /// The converter. public JsonConverter Converter { get; set; } diff --git a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs index 0b8329f9..9b5b19fa 100644 --- a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs @@ -198,7 +198,7 @@ namespace Newtonsoft.Json.Utilities while (current != null) { - if (current.FullName == fullTypeName) + if (string.Equals(current.FullName, fullTypeName, StringComparison.Ordinal)) { match = current; return true; @@ -209,7 +209,7 @@ namespace Newtonsoft.Json.Utilities foreach (Type i in type.GetInterfaces()) { - if (i.Name == fullTypeName) + if (string.Equals(i.Name, fullTypeName, StringComparison.Ordinal)) { match = type; return true;