diff --git a/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs b/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs index 4591e20c..941c2aa9 100644 --- a/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs +++ b/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs @@ -1012,95 +1012,6 @@ namespace Newtonsoft.Json.Tests return (T)converter.ReadJson(reader, typeof(T), null, null); } -#if !(NET20 || NET35 || PORTABLE40) - [Test] - public void Async() - { - Task task = null; - -#pragma warning disable 612,618 - task = JsonConvert.SerializeObjectAsync(42); -#pragma warning restore 612,618 - task.Wait(); - - Assert.AreEqual("42", task.Result); - -#pragma warning disable 612,618 - task = JsonConvert.SerializeObjectAsync(new[] { 1, 2, 3, 4, 5 }, Formatting.Indented); -#pragma warning restore 612,618 - task.Wait(); - - StringAssert.AreEqual(@"[ - 1, - 2, - 3, - 4, - 5 -]", task.Result); - -#pragma warning disable 612,618 - task = JsonConvert.SerializeObjectAsync(DateTime.MaxValue, Formatting.None, new JsonSerializerSettings - { - DateFormatHandling = DateFormatHandling.MicrosoftDateFormat - }); -#pragma warning restore 612,618 - task.Wait(); - - Assert.AreEqual(@"""\/Date(253402300799999)\/""", task.Result); - -#pragma warning disable 612,618 - var taskObject = JsonConvert.DeserializeObjectAsync("[]"); -#pragma warning restore 612,618 - taskObject.Wait(); - - CollectionAssert.AreEquivalent(new JArray(), (JArray)taskObject.Result); - -#pragma warning disable 612,618 - Task taskVersionArray = JsonConvert.DeserializeObjectAsync("['2.0']", typeof(Version[]), new JsonSerializerSettings - { - Converters = { new VersionConverter() } - }); -#pragma warning restore 612,618 - taskVersionArray.Wait(); - - Version[] versionArray = (Version[])taskVersionArray.Result; - - Assert.AreEqual(1, versionArray.Length); - Assert.AreEqual(2, versionArray[0].Major); - -#pragma warning disable 612,618 - Task taskInt = JsonConvert.DeserializeObjectAsync("5"); -#pragma warning restore 612,618 - taskInt.Wait(); - - Assert.AreEqual(5, taskInt.Result); - -#pragma warning disable 612,618 - var taskVersion = JsonConvert.DeserializeObjectAsync("'2.0'", new JsonSerializerSettings - { - Converters = { new VersionConverter() } - }); -#pragma warning restore 612,618 - taskVersion.Wait(); - - Assert.AreEqual(2, taskVersion.Result.Major); - - Movie p = new Movie(); - p.Name = "Existing,"; - -#pragma warning disable 612,618 - Task taskVoid = JsonConvert.PopulateObjectAsync("{'Name':'Appended'}", p, new JsonSerializerSettings - { - Converters = new List { new StringAppenderConverter() } - }); -#pragma warning restore 612,618 - - taskVoid.Wait(); - - Assert.AreEqual("Existing,Appended", p.Name); - } -#endif - [Test] public void SerializeObjectDateTimeZoneHandling() { diff --git a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs index e820434e..e1cc566a 100644 --- a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs +++ b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs @@ -342,9 +342,6 @@ namespace Newtonsoft.Json.Tests.Schema public class CustomDirectoryInfoMapper : DefaultContractResolver { public CustomDirectoryInfoMapper() -#pragma warning disable 612 - : base(true) -#pragma warning restore 612 { } diff --git a/Src/Newtonsoft.Json.Tests/Serialization/CamelCasePropertyNamesContractResolverTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/CamelCasePropertyNamesContractResolverTests.cs index 8f5bc406..74df13b5 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/CamelCasePropertyNamesContractResolverTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/CamelCasePropertyNamesContractResolverTests.cs @@ -44,6 +44,18 @@ namespace Newtonsoft.Json.Tests.Serialization [TestFixture] public class CamelCasePropertyNamesContractResolverTests : TestFixtureBase { + [Test] + public void EnsureContractsShared() + { + CamelCasePropertyNamesContractResolver resolver1 = new CamelCasePropertyNamesContractResolver(); + var contract1 = resolver1.ResolveContract(typeof(CamelCasePropertyNamesContractResolverTests)); + + CamelCasePropertyNamesContractResolver resolver2 = new CamelCasePropertyNamesContractResolver(); + var contract2 = resolver1.ResolveContract(typeof(CamelCasePropertyNamesContractResolverTests)); + + Assert.IsTrue(ReferenceEquals(contract1, contract2)); + } + [Test] public void JsonConvertSerializerSettings() { diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs index 869984d9..63c0e6b3 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs @@ -55,9 +55,6 @@ namespace Newtonsoft.Json.Tests.Serialization private readonly char _startingWithChar; public DynamicContractResolver(char startingWithChar) -#pragma warning disable 612,618 - : base(false) -#pragma warning restore 612,618 { _startingWithChar = startingWithChar; } diff --git a/Src/Newtonsoft.Json/JsonConvert.cs b/Src/Newtonsoft.Json/JsonConvert.cs index dd59b27d..322a31b1 100644 --- a/Src/Newtonsoft.Json/JsonConvert.cs +++ b/Src/Newtonsoft.Json/JsonConvert.cs @@ -29,9 +29,6 @@ using System.Globalization; #if HAVE_BIG_INTEGER using System.Numerics; #endif -#if HAVE_TPL -using System.Threading.Tasks; -#endif using Newtonsoft.Json.Linq; using Newtonsoft.Json.Utilities; using System.Xml; @@ -660,54 +657,6 @@ namespace Newtonsoft.Json return sw.ToString(); } - -#if HAVE_TPL - /// - /// Asynchronously serializes the specified object to a JSON string. - /// Serialization will happen on a new thread. - /// - /// The object to serialize. - /// - /// A task that represents the asynchronous serialization operation. The value of the TResult parameter contains a JSON string representation of the object. - /// - [ObsoleteAttribute("SerializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to serialize JSON asynchronously: Task.Factory.StartNew(() => JsonConvert.SerializeObject(value))")] - public static Task SerializeObjectAsync(object value) - { - return SerializeObjectAsync(value, Formatting.None, null); - } - - /// - /// Asynchronously serializes the specified object to a JSON string using formatting. - /// Serialization will happen on a new thread. - /// - /// The object to serialize. - /// Indicates how the output should be formatted. - /// - /// A task that represents the asynchronous serialization operation. The value of the TResult parameter contains a JSON string representation of the object. - /// - [ObsoleteAttribute("SerializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to serialize JSON asynchronously: Task.Factory.StartNew(() => JsonConvert.SerializeObject(value, formatting))")] - public static Task SerializeObjectAsync(object value, Formatting formatting) - { - return SerializeObjectAsync(value, formatting, null); - } - - /// - /// Asynchronously serializes the specified object to a JSON string using formatting and a collection of . - /// Serialization will happen on a new thread. - /// - /// The object to serialize. - /// Indicates how the output should be formatted. - /// The used to serialize the object. - /// If this is null, default serialization settings will be used. - /// - /// A task that represents the asynchronous serialization operation. The value of the TResult parameter contains a JSON string representation of the object. - /// - [ObsoleteAttribute("SerializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to serialize JSON asynchronously: Task.Factory.StartNew(() => JsonConvert.SerializeObject(value, formatting, settings))")] - public static Task SerializeObjectAsync(object value, Formatting formatting, JsonSerializerSettings settings) - { - return Task.Factory.StartNew(() => SerializeObject(value, formatting, settings)); - } -#endif #endregion #region Deserialize @@ -863,75 +812,6 @@ namespace Newtonsoft.Json return jsonSerializer.Deserialize(reader, type); } } - -#if HAVE_TPL - /// - /// Asynchronously deserializes the JSON to the specified .NET type. - /// Deserialization will happen on a new thread. - /// - /// The type of the object to deserialize to. - /// The JSON to deserialize. - /// - /// A task that represents the asynchronous deserialization operation. The value of the TResult parameter contains the deserialized object from the JSON string. - /// - [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => JsonConvert.DeserializeObject(value))")] - public static Task DeserializeObjectAsync(string value) - { - return DeserializeObjectAsync(value, null); - } - - /// - /// Asynchronously deserializes the JSON to the specified .NET type using . - /// Deserialization will happen on a new thread. - /// - /// The type of the object to deserialize to. - /// The JSON to deserialize. - /// - /// The used to deserialize the object. - /// If this is null, default serialization settings will be used. - /// - /// - /// A task that represents the asynchronous deserialization operation. The value of the TResult parameter contains the deserialized object from the JSON string. - /// - [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => JsonConvert.DeserializeObject(value, settings))")] - public static Task DeserializeObjectAsync(string value, JsonSerializerSettings settings) - { - return Task.Factory.StartNew(() => DeserializeObject(value, settings)); - } - - /// - /// Asynchronously deserializes the JSON to the specified .NET type. - /// Deserialization will happen on a new thread. - /// - /// The JSON to deserialize. - /// - /// A task that represents the asynchronous deserialization operation. The value of the TResult parameter contains the deserialized object from the JSON string. - /// - [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => JsonConvert.DeserializeObject(value))")] - public static Task DeserializeObjectAsync(string value) - { - return DeserializeObjectAsync(value, null, null); - } - - /// - /// Asynchronously deserializes the JSON to the specified .NET type using . - /// Deserialization will happen on a new thread. - /// - /// The JSON to deserialize. - /// The type of the object to deserialize to. - /// - /// The used to deserialize the object. - /// If this is null, default serialization settings will be used. - /// - /// - /// A task that represents the asynchronous deserialization operation. The value of the TResult parameter contains the deserialized object from the JSON string. - /// - [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => JsonConvert.DeserializeObject(value, type, settings))")] - public static Task DeserializeObjectAsync(string value, Type type, JsonSerializerSettings settings) - { - return Task.Factory.StartNew(() => DeserializeObject(value, type, settings)); - } -#endif #endregion #region Populate @@ -974,26 +854,6 @@ namespace Newtonsoft.Json } } } - -#if HAVE_TPL - /// - /// Asynchronously populates the object with values from the JSON string using . - /// - /// The JSON to populate values from. - /// The target object to populate values onto. - /// - /// The used to deserialize the object. - /// If this is null, default serialization settings will be used. - /// - /// - /// A task that represents the asynchronous population operation. - /// - [ObsoleteAttribute("PopulateObjectAsync is obsolete. Use the Task.Factory.StartNew method to populate an object with JSON values asynchronously: Task.Factory.StartNew(() => JsonConvert.PopulateObject(value, target, settings))")] - public static Task PopulateObjectAsync(string value, object target, JsonSerializerSettings settings) - { - return Task.Factory.StartNew(() => PopulateObject(value, target, settings)); - } -#endif #endregion #region Xml diff --git a/Src/Newtonsoft.Json/JsonSerializer.cs b/Src/Newtonsoft.Json/JsonSerializer.cs index 86923e49..27927f87 100644 --- a/Src/Newtonsoft.Json/JsonSerializer.cs +++ b/Src/Newtonsoft.Json/JsonSerializer.cs @@ -951,7 +951,7 @@ namespace Newtonsoft.Json DefaultContractResolver resolver = _contractResolver as DefaultContractResolver; if (resolver != null) { - textReader.NameTable = resolver.GetState().NameTable; + textReader.NameTable = resolver.NameTable; } } } diff --git a/Src/Newtonsoft.Json/JsonSerializerSettings.cs b/Src/Newtonsoft.Json/JsonSerializerSettings.cs index be569074..a4220451 100644 --- a/Src/Newtonsoft.Json/JsonSerializerSettings.cs +++ b/Src/Newtonsoft.Json/JsonSerializerSettings.cs @@ -226,7 +226,7 @@ namespace Newtonsoft.Json /// Gets or sets the used by the serializer when resolving references. /// /// The reference resolver. - [ObsoleteAttribute("ReferenceResolver property is obsolete. Use the ReferenceResolverProvider property to set the IReferenceResolver: settings.ReferenceResolverProvider = () => resolver")] + [Obsolete("ReferenceResolver property is obsolete. Use the ReferenceResolverProvider property to set the IReferenceResolver: settings.ReferenceResolverProvider = () => resolver")] public IReferenceResolver ReferenceResolver { get diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Net40.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Net40.csproj index dceefe54..bd98d1df 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Net40.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Net40.csproj @@ -44,7 +44,7 @@ true - NET40;HAVE_ADO_NET;HAVE_APP_DOMAIN;HAVE_BIG_INTEGER;HAVE_BINARY_SERIALIZATION;HAVE_CAS;HAVE_CHAR_TO_STRING_WITH_CULTURE;HAVE_CHAR_TO_LOWER_WITH_CULTURE;HAVE_COM_ATTRIBUTES;HAVE_COMPONENT_MODEL;HAVE_CONCURRENT_COLLECTIONS;HAVE_COVARIANT_GENERICS;HAVE_DATA_CONTRACTS;HAVE_DATE_TIME_OFFSET;HAVE_DB_NULL_TYPE_CODE;HAVE_DYNAMIC;HAVE_EMPTY_TYPES;HAVE_ENTITY_FRAMEWORK;HAVE_EXPRESSIONS;HAVE_FSHARP_TYPES;HAVE_FULL_REFLECTION;HAVE_GUID_TRY_PARSE;HAVE_HASH_SET;HAVE_ICLONEABLE;HAVE_ICONVERTIBLE;HAVE_IGNORE_DATA_MEMBER_ATTRIBUTE;HAVE_INOTIFY_COLLECTION_CHANGED;HAVE_INOTIFY_PROPERTY_CHANGING;HAVE_ISET;HAVE_LINQ;HAVE_MEMORY_BARRIER;HAVE_NON_SERIALIZED_ATTRIBUTE;HAVE_REFLECTION_EMIT;HAVE_SECURITY_SAFE_CRITICAL_ATTRIBUTE;HAVE_SERIALIZATION_BINDER_BIND_TO_NAME;HAVE_STREAM_READER_WRITER_CLOSE;HAVE_STRING_JOIN_WITH_ENUMERABLE;HAVE_TIME_SPAN_PARSE_WITH_CULTURE;HAVE_TIME_SPAN_TO_STRING_WITH_CULTURE;HAVE_TIME_ZONE_INFO;HAVE_TPL;HAVE_TRACE_WRITER;HAVE_TYPE_DESCRIPTOR;HAVE_UNICODE_SURROGATE_DETECTION;HAVE_VARIANT_TYPE_PARAMETERS;HAVE_VERSION_TRY_PARSE;HAVE_XLINQ;HAVE_XML_DOCUMENT + NET40;HAVE_ADO_NET;HAVE_APP_DOMAIN;HAVE_BIG_INTEGER;HAVE_BINARY_SERIALIZATION;HAVE_CAS;HAVE_CHAR_TO_STRING_WITH_CULTURE;HAVE_CHAR_TO_LOWER_WITH_CULTURE;HAVE_COM_ATTRIBUTES;HAVE_COMPONENT_MODEL;HAVE_CONCURRENT_COLLECTIONS;HAVE_COVARIANT_GENERICS;HAVE_DATA_CONTRACTS;HAVE_DATE_TIME_OFFSET;HAVE_DB_NULL_TYPE_CODE;HAVE_DYNAMIC;HAVE_EMPTY_TYPES;HAVE_ENTITY_FRAMEWORK;HAVE_EXPRESSIONS;HAVE_FSHARP_TYPES;HAVE_FULL_REFLECTION;HAVE_GUID_TRY_PARSE;HAVE_HASH_SET;HAVE_ICLONEABLE;HAVE_ICONVERTIBLE;HAVE_IGNORE_DATA_MEMBER_ATTRIBUTE;HAVE_INOTIFY_COLLECTION_CHANGED;HAVE_INOTIFY_PROPERTY_CHANGING;HAVE_ISET;HAVE_LINQ;HAVE_MEMORY_BARRIER;HAVE_NON_SERIALIZED_ATTRIBUTE;HAVE_REFLECTION_EMIT;HAVE_SECURITY_SAFE_CRITICAL_ATTRIBUTE;HAVE_SERIALIZATION_BINDER_BIND_TO_NAME;HAVE_STREAM_READER_WRITER_CLOSE;HAVE_STRING_JOIN_WITH_ENUMERABLE;HAVE_TIME_SPAN_PARSE_WITH_CULTURE;HAVE_TIME_SPAN_TO_STRING_WITH_CULTURE;HAVE_TIME_ZONE_INFO;HAVE_TRACE_WRITER;HAVE_TYPE_DESCRIPTOR;HAVE_UNICODE_SURROGATE_DETECTION;HAVE_VARIANT_TYPE_PARAMETERS;HAVE_VERSION_TRY_PARSE;HAVE_XLINQ;HAVE_XML_DOCUMENT true diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Portable.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Portable.csproj index 96bdf484..667b06e0 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Portable.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Portable.csproj @@ -13,7 +13,7 @@ 512 {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 11.0 - PORTABLE;HAVE_ASYNC;HAVE_COVARIANT_GENERICS;HAVE_DATA_CONTRACTS;HAVE_DATE_TIME_OFFSET;HAVE_DYNAMIC;HAVE_EXPRESSIONS;HAVE_FSHARP_TYPES;HAVE_GUID_TRY_PARSE;HAVE_IGNORE_DATA_MEMBER_ATTRIBUTE;HAVE_IMMUTABLE_COLLECTIONS;HAVE_ISET;HAVE_LINQ;HAVE_METHOD_IMPL_ATTRIBUTE;HAVE_READ_ONLY_COLLECTIONS;HAVE_REFLECTION_BINDER;HAVE_SERIALIZATION_BINDER_BIND_TO_NAME;HAVE_STRING_JOIN_WITH_ENUMERABLE;HAVE_TIME_SPAN_PARSE_WITH_CULTURE;HAVE_TIME_SPAN_TO_STRING_WITH_CULTURE;HAVE_TIME_ZONE_INFO;HAVE_TPL;HAVE_VARIANT_TYPE_PARAMETERS;HAVE_VERSION_TRY_PARSE;HAVE_XLINQ;HAVE_INOTIFY_COLLECTION_CHANGED + PORTABLE;HAVE_ASYNC;HAVE_COVARIANT_GENERICS;HAVE_DATA_CONTRACTS;HAVE_DATE_TIME_OFFSET;HAVE_DYNAMIC;HAVE_EXPRESSIONS;HAVE_FSHARP_TYPES;HAVE_GUID_TRY_PARSE;HAVE_IGNORE_DATA_MEMBER_ATTRIBUTE;HAVE_IMMUTABLE_COLLECTIONS;HAVE_ISET;HAVE_LINQ;HAVE_METHOD_IMPL_ATTRIBUTE;HAVE_READ_ONLY_COLLECTIONS;HAVE_REFLECTION_BINDER;HAVE_SERIALIZATION_BINDER_BIND_TO_NAME;HAVE_STRING_JOIN_WITH_ENUMERABLE;HAVE_TIME_SPAN_PARSE_WITH_CULTURE;HAVE_TIME_SPAN_TO_STRING_WITH_CULTURE;HAVE_TIME_ZONE_INFO;HAVE_VARIANT_TYPE_PARAMETERS;HAVE_VERSION_TRY_PARSE;HAVE_XLINQ;HAVE_INOTIFY_COLLECTION_CHANGED true diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj index 65c15493..583e6e46 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj @@ -11,7 +11,7 @@ Newtonsoft.Json v4.5 512 - HAVE_ADO_NET;HAVE_APP_DOMAIN;HAVE_ASYNC;HAVE_BIG_INTEGER;HAVE_BINARY_SERIALIZATION;HAVE_CAS;HAVE_CHAR_TO_LOWER_WITH_CULTURE;HAVE_CHAR_TO_STRING_WITH_CULTURE;HAVE_COM_ATTRIBUTES;HAVE_COMPONENT_MODEL;HAVE_CONCURRENT_COLLECTIONS;HAVE_COVARIANT_GENERICS;HAVE_DATA_CONTRACTS;HAVE_DATE_TIME_OFFSET;HAVE_DB_NULL_TYPE_CODE;HAVE_DYNAMIC;HAVE_EMPTY_TYPES;HAVE_ENTITY_FRAMEWORK;HAVE_EXPRESSIONS;HAVE_FSHARP_TYPES;HAVE_FULL_REFLECTION;HAVE_GUID_TRY_PARSE;HAVE_HASH_SET;HAVE_ICLONEABLE;HAVE_ICONVERTIBLE;HAVE_IGNORE_DATA_MEMBER_ATTRIBUTE;HAVE_IMMUTABLE_COLLECTIONS;HAVE_INOTIFY_COLLECTION_CHANGED;HAVE_INOTIFY_PROPERTY_CHANGING;HAVE_ISET;HAVE_LINQ;HAVE_MEMORY_BARRIER;HAVE_METHOD_IMPL_ATTRIBUTE;HAVE_NON_SERIALIZED_ATTRIBUTE;HAVE_READ_ONLY_COLLECTIONS;HAVE_REFLECTION_EMIT;HAVE_SECURITY_SAFE_CRITICAL_ATTRIBUTE;HAVE_SERIALIZATION_BINDER_BIND_TO_NAME;HAVE_STREAM_READER_WRITER_CLOSE;HAVE_STRING_JOIN_WITH_ENUMERABLE;HAVE_TIME_SPAN_PARSE_WITH_CULTURE;HAVE_TIME_SPAN_TO_STRING_WITH_CULTURE;HAVE_TIME_ZONE_INFO;HAVE_TPL;HAVE_TRACE_WRITER;HAVE_TYPE_DESCRIPTOR;HAVE_UNICODE_SURROGATE_DETECTION;HAVE_VARIANT_TYPE_PARAMETERS;HAVE_VERSION_TRY_PARSE;HAVE_XLINQ;HAVE_XML_DOCUMENT + HAVE_ADO_NET;HAVE_APP_DOMAIN;HAVE_ASYNC;HAVE_BIG_INTEGER;HAVE_BINARY_SERIALIZATION;HAVE_CAS;HAVE_CHAR_TO_LOWER_WITH_CULTURE;HAVE_CHAR_TO_STRING_WITH_CULTURE;HAVE_COM_ATTRIBUTES;HAVE_COMPONENT_MODEL;HAVE_CONCURRENT_COLLECTIONS;HAVE_COVARIANT_GENERICS;HAVE_DATA_CONTRACTS;HAVE_DATE_TIME_OFFSET;HAVE_DB_NULL_TYPE_CODE;HAVE_DYNAMIC;HAVE_EMPTY_TYPES;HAVE_ENTITY_FRAMEWORK;HAVE_EXPRESSIONS;HAVE_FSHARP_TYPES;HAVE_FULL_REFLECTION;HAVE_GUID_TRY_PARSE;HAVE_HASH_SET;HAVE_ICLONEABLE;HAVE_ICONVERTIBLE;HAVE_IGNORE_DATA_MEMBER_ATTRIBUTE;HAVE_IMMUTABLE_COLLECTIONS;HAVE_INOTIFY_COLLECTION_CHANGED;HAVE_INOTIFY_PROPERTY_CHANGING;HAVE_ISET;HAVE_LINQ;HAVE_MEMORY_BARRIER;HAVE_METHOD_IMPL_ATTRIBUTE;HAVE_NON_SERIALIZED_ATTRIBUTE;HAVE_READ_ONLY_COLLECTIONS;HAVE_REFLECTION_EMIT;HAVE_SECURITY_SAFE_CRITICAL_ATTRIBUTE;HAVE_SERIALIZATION_BINDER_BIND_TO_NAME;HAVE_STREAM_READER_WRITER_CLOSE;HAVE_STRING_JOIN_WITH_ENUMERABLE;HAVE_TIME_SPAN_PARSE_WITH_CULTURE;HAVE_TIME_SPAN_TO_STRING_WITH_CULTURE;HAVE_TIME_ZONE_INFO;HAVE_TRACE_WRITER;HAVE_TYPE_DESCRIPTOR;HAVE_UNICODE_SURROGATE_DETECTION;HAVE_VARIANT_TYPE_PARAMETERS;HAVE_VERSION_TRY_PARSE;HAVE_XLINQ;HAVE_XML_DOCUMENT true diff --git a/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs b/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs index 46085d58..8a7088e4 100644 --- a/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs @@ -23,23 +23,57 @@ // OTHER DEALINGS IN THE SOFTWARE. #endregion +using System; +using System.Collections.Generic; using System.Globalization; using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Serialization { + internal struct ResolverContractKey : IEquatable + { + private readonly Type _resolverType; + private readonly Type _contractType; + + public ResolverContractKey(Type resolverType, Type contractType) + { + _resolverType = resolverType; + _contractType = contractType; + } + + public override int GetHashCode() + { + return _resolverType.GetHashCode() ^ _contractType.GetHashCode(); + } + + public override bool Equals(object obj) + { + if (!(obj is ResolverContractKey)) + { + return false; + } + + return Equals((ResolverContractKey)obj); + } + + public bool Equals(ResolverContractKey other) + { + return (_resolverType == other._resolverType && _contractType == other._contractType); + } + } + /// /// Resolves member mappings for a type, camel casing property names. /// public class CamelCasePropertyNamesContractResolver : DefaultContractResolver { + private static readonly object TypeContractCacheLock = new object(); + private static Dictionary _contractCache; + /// /// Initializes a new instance of the class. /// public CamelCasePropertyNamesContractResolver() -#pragma warning disable 612,618 - : base(true) -#pragma warning restore 612,618 { NamingStrategy = new CamelCaseNamingStrategy { @@ -47,5 +81,41 @@ namespace Newtonsoft.Json.Serialization OverrideSpecifiedNames = true }; } + + /// + /// Resolves the contract for a given type. + /// + /// The type to resolve a contract for. + /// The contract for a given type. + public override JsonContract ResolveContract(Type type) + { + if (type == null) + { + throw new ArgumentNullException(nameof(type)); + } + + // for backwards compadibility the CamelCasePropertyNamesContractResolver shares contracts between instances + JsonContract contract; + ResolverContractKey key = new ResolverContractKey(GetType(), type); + Dictionary cache = _contractCache; + if (cache == null || !cache.TryGetValue(key, out contract)) + { + contract = CreateContract(type); + + // avoid the possibility of modifying the cache dictionary while another thread is accessing it + lock (TypeContractCacheLock) + { + cache = _contractCache; + Dictionary updatedCache = (cache != null) + ? new Dictionary(cache) + : new Dictionary(); + updatedCache[key] = contract; + + _contractCache = updatedCache; + } + } + + return contract; + } } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs index 8d26e39f..351d5198 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs @@ -53,57 +53,12 @@ using System.Linq; namespace Newtonsoft.Json.Serialization { - internal struct ResolverContractKey : IEquatable - { - private readonly Type _resolverType; - private readonly Type _contractType; - - public ResolverContractKey(Type resolverType, Type contractType) - { - _resolverType = resolverType; - _contractType = contractType; - } - - public override int GetHashCode() - { - return _resolverType.GetHashCode() ^ _contractType.GetHashCode(); - } - - public override bool Equals(object obj) - { - if (!(obj is ResolverContractKey)) - { - return false; - } - - return Equals((ResolverContractKey)obj); - } - - public bool Equals(ResolverContractKey other) - { - return (_resolverType == other._resolverType && _contractType == other._contractType); - } - } - - internal class DefaultContractResolverState - { - public Dictionary ContractCache; - public PropertyNameTable NameTable = new PropertyNameTable(); - } - /// /// Used by to resolve a for a given . /// public class DefaultContractResolver : IContractResolver { -#pragma warning disable 612,618 - private static readonly IContractResolver _instance = new DefaultContractResolver(true); -#pragma warning restore 612,618 - - internal static IContractResolver Instance - { - get { return _instance; } - } + internal static readonly IContractResolver Instance = new DefaultContractResolver(); private static readonly JsonConverter[] BuiltInConverters = { @@ -129,11 +84,10 @@ namespace Newtonsoft.Json.Serialization new RegexConverter() }; - private static readonly object TypeContractCacheLock = new object(); + private readonly object _typeContractCacheLock = new object(); + internal readonly PropertyNameTable NameTable = new PropertyNameTable(); - private static readonly DefaultContractResolverState _sharedState = new DefaultContractResolverState(); - private readonly DefaultContractResolverState _instanceState = new DefaultContractResolverState(); - private readonly bool _sharedCache; + private Dictionary _contractCache; /// /// Gets a value indicating whether members are being get and set using dynamic code generation. @@ -152,7 +106,7 @@ namespace Newtonsoft.Json.Serialization /// Gets or sets the default members search flags. /// /// The default members search flags. - [ObsoleteAttribute("DefaultMembersSearchFlags is obsolete. To modify the members serialized inherit from DefaultContractResolver and override the GetSerializableMembers method instead.")] + [Obsolete("DefaultMembersSearchFlags is obsolete. To modify the members serialized inherit from DefaultContractResolver and override the GetSerializableMembers method instead.")] public BindingFlags DefaultMembersSearchFlags { get; set; } #else private BindingFlags DefaultMembersSearchFlags; @@ -204,34 +158,6 @@ namespace Newtonsoft.Json.Serialization #pragma warning restore 618 } - /// - /// Initializes a new instance of the class. - /// - /// - /// If set to true the will use a cached shared with other resolvers of the same type. - /// Sharing the cache will significantly improve performance with multiple resolver instances because expensive reflection will only - /// happen once. This setting can cause unexpected behavior if different instances of the resolver are suppose to produce different - /// results. When set to false it is highly recommended to reuse instances with the . - /// - [ObsoleteAttribute("DefaultContractResolver(bool) is obsolete. Use the parameterless constructor and cache instances of the contract resolver within your application for optimal performance.")] - public DefaultContractResolver(bool shareCache) - : this() - { - _sharedCache = shareCache; - } - - internal DefaultContractResolverState GetState() - { - if (_sharedCache) - { - return _sharedState; - } - else - { - return _instanceState; - } - } - /// /// Resolves the contract for a given type. /// @@ -244,25 +170,22 @@ namespace Newtonsoft.Json.Serialization throw new ArgumentNullException(nameof(type)); } - DefaultContractResolverState state = GetState(); - JsonContract contract; - ResolverContractKey key = new ResolverContractKey(GetType(), type); - Dictionary cache = state.ContractCache; - if (cache == null || !cache.TryGetValue(key, out contract)) + Dictionary cache = _contractCache; + if (cache == null || !cache.TryGetValue(type, out contract)) { contract = CreateContract(type); // avoid the possibility of modifying the cache dictionary while another thread is accessing it - lock (TypeContractCacheLock) + lock (_typeContractCacheLock) { - cache = state.ContractCache; - Dictionary updatedCache = (cache != null) - ? new Dictionary(cache) - : new Dictionary(); - updatedCache[key] = contract; + cache = _contractCache; + Dictionary updatedCache = (cache != null) + ? new Dictionary(cache) + : new Dictionary(); + updatedCache[type] = contract; - state.ContractCache = updatedCache; + _contractCache = updatedCache; } } @@ -1324,12 +1247,10 @@ namespace Newtonsoft.Json.Serialization if (property != null) { - DefaultContractResolverState state = GetState(); - // nametable is not thread-safe for multiple writers - lock (state.NameTable) + lock (NameTable) { - property.PropertyName = state.NameTable.Add(property.PropertyName); + property.PropertyName = NameTable.Add(property.PropertyName); } properties.AddProperty(property); diff --git a/Src/Newtonsoft.Json/project.json b/Src/Newtonsoft.Json/project.json index 403269da..d6c7defb 100644 --- a/Src/Newtonsoft.Json/project.json +++ b/Src/Newtonsoft.Json/project.json @@ -72,7 +72,6 @@ "HAVE_TIME_SPAN_PARSE_WITH_CULTURE", "HAVE_TIME_SPAN_TO_STRING_WITH_CULTURE", "HAVE_TIME_ZONE_INFO", - "HAVE_TPL", "HAVE_VARIANT_TYPE_PARAMETERS", "HAVE_VERSION_TRY_PARSE", "HAVE_XLINQ", @@ -171,7 +170,6 @@ "HAVE_TIME_SPAN_PARSE_WITH_CULTURE", "HAVE_TIME_SPAN_TO_STRING_WITH_CULTURE", "HAVE_TIME_ZONE_INFO", - "HAVE_TPL", "HAVE_TYPE_DESCRIPTOR", "HAVE_UNICODE_SURROGATE_DETECTION", "HAVE_VARIANT_TYPE_PARAMETERS", @@ -233,7 +231,6 @@ "HAVE_TIME_SPAN_PARSE_WITH_CULTURE", "HAVE_TIME_SPAN_TO_STRING_WITH_CULTURE", "HAVE_TIME_ZONE_INFO", - "HAVE_TPL", "HAVE_TYPE_DESCRIPTOR", "HAVE_UNICODE_SURROGATE_DETECTION", "HAVE_VARIANT_TYPE_PARAMETERS",