-Added DateTimeConverterBase

-Changed class converter to be resolved from contract
-Changed built in converters to be resolved once when the contract is created. Big performance gain!
This commit is contained in:
JamesNK
2009-12-26 18:51:39 +00:00
parent f574bfbf83
commit 9144bc6c80
29 changed files with 244 additions and 133 deletions
+12 -2
View File
@@ -15,8 +15,18 @@
<div id="content">
<span style="color: DarkGray"> </span>
<p><a href="./html/M_Newtonsoft_Json_Linq_JToken_SelectToken.htm">SelectToken</a> provides a method to query LINQ to JSON using a single string path to a
desired <a href="./html/T_Newtonsoft_Json_Linq_JToken.htm">JToken</a>. SelectToken makes dynamic queries much easier because the entire
desired <a href="./html/T_Newtonsoft_Json_Linq_JToken.htm">JToken</a>. SelectToken makes dynamic queries
easy because the entire
query is defined in a string.</p>
<div class="overflowpanel">
<div class="code">
<div style="font-family: Courier New; font-size: 10pt; color: black;">
<pre style="margin: 0px;"><span style="color: blue;">string</span> name = (<span style="color: blue;">string</span>)o.SelectToken(<span style="color: #a31515;">&quot;Manufacturers[0].Name&quot;</span>);</pre>
</div>
</div>
</div>
<h3>SelectToken</h3>
<p>SelectToken is a method on JToken and takes a string path to a child token.
@@ -25,7 +35,7 @@
<p>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: <code>Manufacturers[0].Name</code>
of the following are valid paths and are equivalent to each other: <code>Manufacturers[0].Name</code>
and <code>Manufacturers(0).Name</code>.</p>
<div class="overflowpanel">
@@ -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<Product>(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);
}
}
}
@@ -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<DataSet>(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;
}
@@ -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);
+1 -1
View File
@@ -36,7 +36,7 @@ namespace Newtonsoft.Json.Tests
[TestFixture]
public abstract class TestFixtureBase
{
[TestFixtureSetUp]
[SetUp]
protected void TestSetup()
{
//CultureInfo turkey = CultureInfo.CreateSpecificCulture("tr");
@@ -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
-1
View File
@@ -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;
-5
View File
@@ -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
+19 -3
View File
@@ -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
}
}
/// <summary>
/// Writes out a comment <code>/*...*/</code> containing the specified text.
/// </summary>
/// <param name="text">Text to place inside the comment.</param>
public override void WriteComment(string text)
{
throw new JsonWriterException("Cannot write JSON comment as BSON.");
}
/// <summary>
/// Writes the start of a constructor with the given name.
/// </summary>
/// <param name="name">The name of the constructor.</param>
public override void WriteStartConstructor(string name)
{
throw new JsonWriterException("Cannot write JSON constructor as BSON.");
}
/// <summary>
/// Writes raw JSON.
/// </summary>
/// <param name="json">The raw JSON to write.</param>
public override void WriteRaw(string json)
{
throw new JsonWriterException("Cannot write raw JSON as BSON.");
}
/// <summary>
/// Writes raw JSON where a value is expected and updates the writer's state.
/// </summary>
/// <param name="json">The raw JSON to write.</param>
public override void WriteRawValue(string json)
{
throw new JsonWriterException("Cannot write raw JSON as BSON.");
@@ -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
/// </returns>
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;
@@ -24,9 +24,6 @@
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Newtonsoft.Json.Converters
{
@@ -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
{
@@ -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
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Newtonsoft.Json.Converters
{
/// <summary>
/// Provides a base class for converting a <see cref="DateTime"/> to and from JSON.
/// </summary>
public abstract class DateTimeConverterBase : JsonConverter
{
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
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;
}
}
}
@@ -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
{
@@ -25,8 +25,6 @@
#if !SILVERLIGHT && !PocketPC
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
namespace Newtonsoft.Json.Converters
@@ -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
/// <summary>
/// Converts a <see cref="DateTime"/> to and from the ISO 8601 date format (e.g. 2008-04-12T12:53Z).
/// </summary>
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);
}
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
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;
}
}
}
@@ -7,7 +7,7 @@ namespace Newtonsoft.Json.Converters
/// <summary>
/// Converts a <see cref="DateTime"/> to and from a JavaScript date constructor (e.g. new Date(52231943)).
/// </summary>
public class JavaScriptDateTimeConverter : JsonConverter
public class JavaScriptDateTimeConverter : DateTimeConverterBase
{
/// <summary>
/// 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;
}
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
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;
}
}
}
@@ -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++)
+15 -15
View File
@@ -54,18 +54,6 @@ namespace Newtonsoft.Json
private IReferenceResolver _referenceResolver;
private SerializationBinder _binder;
private static readonly IList<JsonConverter> BuiltInConverters = new List<JsonConverter>
{
#if !PocketPC && !SILVERLIGHT && !NET20
new EntityKeyMemberConverter(),
#endif
new BinaryConverter(),
#if !SILVERLIGHT
new DataSetConverter(),
new DataTableConverter()
#endif
};
/// <summary>
/// Occurs when the <see cref="JsonSerializer"/> errors during serialization and deserialization.
/// </summary>
@@ -368,6 +356,18 @@ namespace Newtonsoft.Json
return Deserialize(new JsonTextReader(reader), objectType);
}
/// <summary>
/// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>
/// into an instance of the specified type.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> containing the object.</param>
/// <typeparam name="T">The type of the object to deserialize.</typeparam>
/// <returns>The instance of <typeparamref name="T"/> being deserialized.</returns>
public T Deserialize<T>(JsonReader reader)
{
return (T)Deserialize(reader, typeof(T));
}
/// <summary>
/// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>
/// 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;
}
+4
View File
@@ -183,6 +183,10 @@ namespace Newtonsoft.Json.Linq
AddValue(JValue.CreateRaw(json), JsonToken.Raw);
}
/// <summary>
/// Writes out a comment <code>/*...*/</code> containing the specified text.
/// </summary>
/// <param name="text">Text to place inside the comment.</param>
public override void WriteComment(string text)
{
base.WriteComment(text);
@@ -62,6 +62,7 @@
<Compile Include="Converters\CustomCreationConverter.cs" />
<Compile Include="Converters\DataSetConverter.cs" />
<Compile Include="Converters\DataTableConverter.cs" />
<Compile Include="Converters\DateTimeConverterBase.cs" />
<Compile Include="Converters\EntityKeyMemberConverter.cs" />
<Compile Include="Converters\StringEnumConverter.cs" />
<Compile Include="IJsonLineInfo.cs" />
@@ -82,6 +82,7 @@
<Compile Include="Converters\CustomCreationConverter.cs" />
<Compile Include="Converters\DataSetConverter.cs" />
<Compile Include="Converters\DataTableConverter.cs" />
<Compile Include="Converters\DateTimeConverterBase.cs" />
<Compile Include="Converters\EntityKeyMemberConverter.cs" />
<Compile Include="Converters\StringEnumConverter.cs" />
<Compile Include="Linq\ComponentModel\JPropertyDescriptor.cs" />
@@ -59,6 +59,7 @@
<Compile Include="Converters\CustomCreationConverter.cs" />
<Compile Include="Converters\DataSetConverter.cs" />
<Compile Include="Converters\DataTableConverter.cs" />
<Compile Include="Converters\DateTimeConverterBase.cs" />
<Compile Include="Converters\EntityKeyMemberConverter.cs" />
<Compile Include="Converters\IsoDateTimeConverter.cs" />
<Compile Include="Converters\JavaScriptDateTimeConverter.cs" />
@@ -85,6 +85,7 @@
<Compile Include="Converters\DataSetConverter.cs" />
<Compile Include="Converters\DataTableConverter.cs" />
<Compile Include="Converters\CustomCreationConverter.cs" />
<Compile Include="Converters\DateTimeConverterBase.cs" />
<Compile Include="Converters\EntityKeyMemberConverter.cs" />
<Compile Include="Converters\StringEnumConverter.cs" />
<Compile Include="ConstructorHandling.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<JsonConverter> BuiltInConverters = new List<JsonConverter>
{
#if !PocketPC && !SILVERLIGHT && !NET20
new EntityKeyMemberConverter(),
#endif
new BinaryConverter(),
#if !SILVERLIGHT
new DataSetConverter(),
new DataTableConverter()
#endif
};
private readonly ThreadSafeStore<Type, JsonContract> _typeContractCache;
@@ -154,6 +166,23 @@ namespace Newtonsoft.Json.Serialization
return null;
}
/// <summary>
/// Resolves the default <see cref="JsonConverter" /> for the contract.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns></returns>
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
@@ -53,6 +53,12 @@ namespace Newtonsoft.Json.Serialization
/// <value>Whether this type contract is serialized as a reference.</value>
public bool? IsReference { get; set; }
/// <summary>
/// Gets or sets the default <see cref="JsonConverter" /> for this contract.
/// </summary>
/// <value>The converter.</value>
public JsonConverter Converter { get; set; }
private static readonly StreamingContext SerializationStreamingContextParameter = new StreamingContext();
private static readonly object[] SerializationEventParameterValues = new object[] { SerializationStreamingContextParameter };
@@ -51,7 +51,8 @@ namespace Newtonsoft.Json.Serialization
public Type PropertyType { get; set; }
/// <summary>
/// Gets or sets the converter.
/// Gets or sets the <see cref="JsonConverter" /> for the property.
/// If set this converter takes presidence over the contract converter for the property type.
/// </summary>
/// <value>The converter.</value>
public JsonConverter Converter { get; set; }
@@ -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;