Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/Newtonsoft.Json.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamesNK <james@newtonking.com>2012-01-22 05:51:01 +0400
committerJamesNK <james@newtonking.com>2012-01-22 05:51:01 +0400
commit58d51cda5c3ee6e3fd5c3b826ae15e65423d9c31 (patch)
tree1373c96cb07a98c7ca74f22f986845c4af894bfb
parentcd424a7bc5e08bb3a9ae1266e744ee08c57dbbf9 (diff)
-Added ReadAsInt32 to JsonReader
-Improved performance by using an enum rather than a type check to test contract type
-rw-r--r--Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs30
-rw-r--r--Src/Newtonsoft.Json.Tests/PerformanceTests.cs15
-rw-r--r--Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs2
-rw-r--r--Src/Newtonsoft.Json/Bson/BsonReader.cs26
-rw-r--r--Src/Newtonsoft.Json/Converters/DataTableConverter.cs2
-rw-r--r--Src/Newtonsoft.Json/Converters/RegexConverter.cs4
-rw-r--r--Src/Newtonsoft.Json/JsonConvert.cs26
-rw-r--r--Src/Newtonsoft.Json/JsonReader.cs14
-rw-r--r--Src/Newtonsoft.Json/JsonTextReader.cs69
-rw-r--r--Src/Newtonsoft.Json/JsonToken.cs2
-rw-r--r--Src/Newtonsoft.Json/JsonValidatingReader.cs12
-rw-r--r--Src/Newtonsoft.Json/Linq/JTokenReader.cs22
-rw-r--r--Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs152
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs2
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonContract.cs51
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs2
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs2
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs1
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs1
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs14
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs1
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs100
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs81
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonStringContract.cs1
24 files changed, 396 insertions, 236 deletions
diff --git a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs
index b07921f..6ffcf8a 100644
--- a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs
+++ b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs
@@ -1076,6 +1076,36 @@ bye", reader.Value);
}
[Test]
+ public void ReadOctalNumberAsInt32()
+ {
+ StringReader s = new StringReader(@"[0372, 0xFA, 0XFA]");
+ JsonTextReader jsonReader = new JsonTextReader(s);
+
+ Assert.IsTrue(jsonReader.Read());
+ Assert.AreEqual(JsonToken.StartArray, jsonReader.TokenType);
+
+ jsonReader.ReadAsInt32();
+ Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType);
+ Assert.AreEqual(typeof(int), jsonReader.ValueType);
+ Assert.AreEqual(250, jsonReader.Value);
+
+ jsonReader.ReadAsInt32();
+ Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType);
+ Assert.AreEqual(typeof(int), jsonReader.ValueType);
+ Assert.AreEqual(250, jsonReader.Value);
+
+ jsonReader.ReadAsInt32();
+ Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType);
+ Assert.AreEqual(typeof(int), jsonReader.ValueType);
+ Assert.AreEqual(250, jsonReader.Value);
+
+ Assert.IsTrue(jsonReader.Read());
+ Assert.AreEqual(JsonToken.EndArray, jsonReader.TokenType);
+
+ Assert.IsFalse(jsonReader.Read());
+ }
+
+ [Test]
[ExpectedException(typeof(JsonReaderException), ExpectedMessage = "Unexpected character encountered while parsing value: }. Line 1, position 1.")]
public void ReadBadCharInArray()
{
diff --git a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
index 11e0dc1..160cbd0 100644
--- a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
+++ b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
@@ -36,8 +36,8 @@ namespace Newtonsoft.Json.Tests
public class PerformanceTests : TestFixtureBase
{
- private const int Iterations = 100;
- //private const int Iterations = 5000;
+ //private const int Iterations = 100;
+ private const int Iterations = 5000;
private static SimpleObject CreateSimpleObject()
{
@@ -101,12 +101,12 @@ namespace Newtonsoft.Json.Tests
private void SerializeTests(object value)
{
- //BenchmarkSerializeMethod(SerializeMethod.DataContractSerializer, value);
- ////BenchmarkSerializeMethod(SerializeMethod.BinaryFormatter, value);
- //BenchmarkSerializeMethod(SerializeMethod.JavaScriptSerializer, value);
- //BenchmarkSerializeMethod(SerializeMethod.DataContractJsonSerializer, value);
+ BenchmarkSerializeMethod(SerializeMethod.DataContractSerializer, value);
+ BenchmarkSerializeMethod(SerializeMethod.BinaryFormatter, value);
+ BenchmarkSerializeMethod(SerializeMethod.JavaScriptSerializer, value);
+ BenchmarkSerializeMethod(SerializeMethod.DataContractJsonSerializer, value);
BenchmarkSerializeMethod(SerializeMethod.JsonNet, value);
- //BenchmarkSerializeMethod(SerializeMethod.JsonNetBinary, value);
+ BenchmarkSerializeMethod(SerializeMethod.JsonNetBinary, value);
}
[Test]
@@ -763,6 +763,7 @@ namespace Newtonsoft.Json.Tests
}
[DataContract]
+ [Serializable]
public class SimpleObject
{
[DataMember]
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
index 13b8783..b0fe562 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
@@ -1931,7 +1931,7 @@ keyword such as type of business.""
}
[Test]
- [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Error converting value """" to type 'System.Int32'. Line 1, position 15.")]
+ [ExpectedException(typeof(JsonReaderException), ExpectedMessage = @"Could not convert string to integer: . Line 1, position 15.")]
public void DeserializeEnsureTypeEmptyStringToIntError()
{
JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:''}");
diff --git a/Src/Newtonsoft.Json/Bson/BsonReader.cs b/Src/Newtonsoft.Json/Bson/BsonReader.cs
index a36bb92..0d17885 100644
--- a/Src/Newtonsoft.Json/Bson/BsonReader.cs
+++ b/Src/Newtonsoft.Json/Bson/BsonReader.cs
@@ -193,7 +193,7 @@ namespace Newtonsoft.Json.Bson
if (TokenType == JsonToken.Null)
return null;
if (TokenType == JsonToken.Bytes)
- return (byte[]) Value;
+ return (byte[])Value;
if (ReaderIsSerializerInArray())
return null;
@@ -238,7 +238,7 @@ namespace Newtonsoft.Json.Bson
if (TokenType == JsonToken.Integer || TokenType == JsonToken.Float)
{
SetToken(JsonToken.Float, Convert.ToDecimal(Value, CultureInfo.InvariantCulture));
- return (decimal) Value;
+ return (decimal)Value;
}
if (ReaderIsSerializerInArray())
@@ -247,6 +247,28 @@ namespace Newtonsoft.Json.Bson
throw new JsonReaderException("Error reading decimal. Expected a number but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
}
+ /// <summary>
+ /// Reads the next JSON token from the stream as a <see cref="Nullable{Int32}"/>.
+ /// </summary>
+ /// <returns>A <see cref="Nullable{Int32}"/>.</returns>
+ public override int? ReadAsInt32()
+ {
+ Read();
+
+ if (TokenType == JsonToken.Integer || TokenType == JsonToken.Float)
+ {
+ SetToken(JsonToken.Float, Convert.ToInt32(Value, CultureInfo.InvariantCulture));
+ return (int)Value;
+ }
+ if (TokenType == JsonToken.Null)
+ return null;
+
+ if (ReaderIsSerializerInArray())
+ return null;
+
+ throw new JsonReaderException("Error reading integer. Expected a number but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+ }
+
#if !NET20
/// <summary>
/// Reads the next JSON token from the stream as a <see cref="Nullable{DateTimeOffset}"/>.
diff --git a/Src/Newtonsoft.Json/Converters/DataTableConverter.cs b/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
index c08324c..ec0de77 100644
--- a/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
@@ -96,7 +96,7 @@ namespace Newtonsoft.Json.Converters
while (reader.TokenType == JsonToken.PropertyName)
{
- string columnName = (string) reader.Value;
+ string columnName = (string)reader.Value;
reader.Read();
diff --git a/Src/Newtonsoft.Json/Converters/RegexConverter.cs b/Src/Newtonsoft.Json/Converters/RegexConverter.cs
index bd589bc..02ef524 100644
--- a/Src/Newtonsoft.Json/Converters/RegexConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/RegexConverter.cs
@@ -93,7 +93,7 @@ namespace Newtonsoft.Json.Converters
private object ReadBson(BsonReader reader)
{
- string regexText = (string) reader.Value;
+ string regexText = (string)reader.Value;
int patternOptionDelimiterIndex = regexText.LastIndexOf('/');
string patternText = regexText.Substring(1, patternOptionDelimiterIndex - 1);
@@ -126,7 +126,7 @@ namespace Newtonsoft.Json.Converters
{
reader.Read();
reader.Read();
- string pattern = (string) reader.Value;
+ string pattern = (string)reader.Value;
reader.Read();
reader.Read();
diff --git a/Src/Newtonsoft.Json/JsonConvert.cs b/Src/Newtonsoft.Json/JsonConvert.cs
index 4f9b89a..556a7f8 100644
--- a/Src/Newtonsoft.Json/JsonConvert.cs
+++ b/Src/Newtonsoft.Json/JsonConvert.cs
@@ -529,32 +529,6 @@ namespace Newtonsoft.Json
return IsJsonPrimitiveTypeCode(Type.GetTypeCode(type));
}
- internal static bool IsJsonPrimitive(object value)
- {
- if (value == null)
- return true;
-
- IConvertible convertible = value as IConvertible;
-
- if (convertible != null)
- return IsJsonPrimitiveTypeCode(convertible.GetTypeCode());
-
-#if !PocketPC && !NET20
- if (value is DateTimeOffset)
- return true;
-#endif
- if (value is byte[])
- return true;
- if (value is Uri)
- return true;
- if (value is TimeSpan)
- return true;
- if (value is Guid)
- return true;
-
- return false;
- }
-
/// <summary>
/// Serializes the specified object to a JSON string.
/// </summary>
diff --git a/Src/Newtonsoft.Json/JsonReader.cs b/Src/Newtonsoft.Json/JsonReader.cs
index 0e919e7..b22fba3 100644
--- a/Src/Newtonsoft.Json/JsonReader.cs
+++ b/Src/Newtonsoft.Json/JsonReader.cs
@@ -97,7 +97,7 @@ namespace Newtonsoft.Json
}
// current Token data
- private JsonToken _token;
+ private JsonToken _tokenType;
private object _value;
private char _quoteChar;
internal State _currentState;
@@ -146,7 +146,7 @@ namespace Newtonsoft.Json
/// </summary>
public virtual JsonToken TokenType
{
- get { return _token; }
+ get { return _tokenType; }
}
/// <summary>
@@ -223,6 +223,12 @@ namespace Newtonsoft.Json
public abstract bool Read();
/// <summary>
+ /// Reads the next JSON token from the stream as a <see cref="Nullable{Int32}"/>.
+ /// </summary>
+ /// <returns>A <see cref="Nullable{Int32}"/>.</returns>
+ public abstract int? ReadAsInt32();
+
+ /// <summary>
/// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
/// </summary>
/// <returns>A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.</returns>
@@ -276,7 +282,7 @@ namespace Newtonsoft.Json
/// <param name="value">The value.</param>
protected void SetToken(JsonToken newToken, object value)
{
- _token = newToken;
+ _tokenType = newToken;
switch (newToken)
{
@@ -447,7 +453,7 @@ namespace Newtonsoft.Json
public virtual void Close()
{
_currentState = State.Closed;
- _token = JsonToken.None;
+ _tokenType = JsonToken.None;
_value = null;
}
diff --git a/Src/Newtonsoft.Json/JsonTextReader.cs b/Src/Newtonsoft.Json/JsonTextReader.cs
index 6455bd0..6598777 100644
--- a/Src/Newtonsoft.Json/JsonTextReader.cs
+++ b/Src/Newtonsoft.Json/JsonTextReader.cs
@@ -42,6 +42,7 @@ namespace Newtonsoft.Json
private enum ReadType
{
Read,
+ ReadAsInt32,
ReadAsBytes,
ReadAsDecimal,
#if !NET20
@@ -459,6 +460,45 @@ namespace Newtonsoft.Json
throw CreateReaderException(this, "Unexpected token when reading decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
}
+ /// <summary>
+ /// Reads the next JSON token from the stream as a <see cref="Nullable{Int32}"/>.
+ /// </summary>
+ /// <returns>A <see cref="Nullable{Int32}"/>.</returns>
+ public override int? ReadAsInt32()
+ {
+ _readType = ReadType.ReadAsInt32;
+
+ do
+ {
+ if (!ReadInternal())
+ throw CreateReaderException(this, "Unexpected end when reading integer.");
+ } while (TokenType == JsonToken.Comment);
+
+ if (TokenType == JsonToken.Integer)
+ return (int?)Value;
+ if (TokenType == JsonToken.Null)
+ return null;
+
+ int i;
+ if (TokenType == JsonToken.String)
+ {
+ if (int.TryParse((string)Value, NumberStyles.Integer, Culture, out i))
+ {
+ SetToken(JsonToken.Integer, i);
+ return i;
+ }
+ else
+ {
+ throw CreateReaderException(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, Value));
+ }
+ }
+
+ if (ReaderIsSerializerInArray())
+ return null;
+
+ throw CreateReaderException(this, "Unexpected token when reading integer: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+ }
+
#if !NET20
/// <summary>
/// Reads the next JSON token from the stream as a <see cref="Nullable{DateTimeOffset}"/>.
@@ -1223,7 +1263,34 @@ namespace Newtonsoft.Json
bool singleDigit = (char.IsDigit(firstChar) && _stringReference.Length == 1);
bool nonBase10 = (firstChar == '0' && _stringReference.Length > 1 && _stringReference.Chars[_stringReference.StartIndex + 1] != '.');
- if (_readType == ReadType.ReadAsDecimal)
+ if (_readType == ReadType.ReadAsInt32)
+ {
+ if (singleDigit)
+ {
+ // digit char values start at 48
+ numberValue = firstChar - 48;
+ }
+ else if (nonBase10)
+ {
+ string number = _stringReference.ToString();
+
+ // decimal.Parse doesn't support parsing hexadecimal values
+ int integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
+ ? Convert.ToInt32(number, 16)
+ : Convert.ToInt32(number, 8);
+
+ numberValue = integer;
+ }
+ else
+ {
+ string number = _stringReference.ToString();
+
+ numberValue = Convert.ToInt32(number, CultureInfo.InvariantCulture);
+ }
+
+ numberType = JsonToken.Integer;
+ }
+ else if (_readType == ReadType.ReadAsDecimal)
{
if (singleDigit)
{
diff --git a/Src/Newtonsoft.Json/JsonToken.cs b/Src/Newtonsoft.Json/JsonToken.cs
index 5870c42..ca05bcd 100644
--- a/Src/Newtonsoft.Json/JsonToken.cs
+++ b/Src/Newtonsoft.Json/JsonToken.cs
@@ -63,7 +63,7 @@ namespace Newtonsoft.Json
/// </summary>
Raw,
/// <summary>
- /// An interger.
+ /// An integer.
/// </summary>
Integer,
/// <summary>
diff --git a/Src/Newtonsoft.Json/JsonValidatingReader.cs b/Src/Newtonsoft.Json/JsonValidatingReader.cs
index a6e199b..4e2f691 100644
--- a/Src/Newtonsoft.Json/JsonValidatingReader.cs
+++ b/Src/Newtonsoft.Json/JsonValidatingReader.cs
@@ -345,6 +345,18 @@ namespace Newtonsoft.Json
}
/// <summary>
+ /// Reads the next JSON token from the stream as a <see cref="Nullable{Int32}"/>.
+ /// </summary>
+ /// <returns>A <see cref="Nullable{Int32}"/>.</returns>
+ public override int? ReadAsInt32()
+ {
+ int? i = _reader.ReadAsInt32();
+
+ ValidateCurrentToken();
+ return i;
+ }
+
+ /// <summary>
/// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
/// </summary>
/// <returns>
diff --git a/Src/Newtonsoft.Json/Linq/JTokenReader.cs b/Src/Newtonsoft.Json/Linq/JTokenReader.cs
index 807f044..e52fc75 100644
--- a/Src/Newtonsoft.Json/Linq/JTokenReader.cs
+++ b/Src/Newtonsoft.Json/Linq/JTokenReader.cs
@@ -111,6 +111,28 @@ namespace Newtonsoft.Json.Linq
throw new JsonReaderException("Error reading decimal. Expected a number but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
}
+ /// <summary>
+ /// Reads the next JSON token from the stream as a <see cref="Nullable{Int32}"/>.
+ /// </summary>
+ /// <returns>A <see cref="Nullable{Int32}"/>.</returns>
+ public override int? ReadAsInt32()
+ {
+ Read();
+
+ if (TokenType == JsonToken.Integer || TokenType == JsonToken.Float)
+ {
+ SetToken(JsonToken.Integer, Convert.ToInt32(Value, CultureInfo.InvariantCulture));
+ return (int)Value;
+ }
+ if (TokenType == JsonToken.Null)
+ return null;
+
+ if (ReaderIsSerializerInArray())
+ return null;
+
+ throw new JsonReaderException("Error reading integer. Expected a number but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+ }
+
#if !NET20
/// <summary>
/// Reads the next JSON token from the stream as a <see cref="Nullable{DateTimeOffset}"/>.
diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs
index 4ab2614..f30643b 100644
--- a/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs
+++ b/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs
@@ -258,87 +258,85 @@ namespace Newtonsoft.Json.Schema
// todo: Add GetSchema to JsonConverter and use here?
CurrentSchema.Type = JsonSchemaType.Any;
}
- else if (contract is JsonDictionaryContract)
- {
- CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
-
- Type keyType;
- Type valueType;
- ReflectionUtils.GetDictionaryKeyValueTypes(type, out keyType, out valueType);
-
- if (keyType != null)
- {
- // can be converted to a string
- if (typeof (IConvertible).IsAssignableFrom(keyType))
- {
- CurrentSchema.AdditionalProperties = GenerateInternal(valueType, Required.Default, false);
- }
- }
- }
- else if (contract is JsonArrayContract)
- {
- CurrentSchema.Type = AddNullType(JsonSchemaType.Array, valueRequired);
-
- CurrentSchema.Id = GetTypeId(type, false);
-
- JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute;
- bool allowNullItem = (arrayAttribute == null || arrayAttribute.AllowNullItems);
-
- Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
- if (collectionItemType != null)
- {
- CurrentSchema.Items = new List<JsonSchema>();
- CurrentSchema.Items.Add(GenerateInternal(collectionItemType, (!allowNullItem) ? Required.Always : Required.Default, false));
- }
- }
- else if (contract is JsonStringContract)
- {
- JsonSchemaType schemaType = (!ReflectionUtils.IsNullable(contract.UnderlyingType))
- ? JsonSchemaType.String
- : AddNullType(JsonSchemaType.String, valueRequired);
-
- CurrentSchema.Type = schemaType;
- }
- else if (contract is JsonPrimitiveContract)
+ else
{
- CurrentSchema.Type = GetJsonSchemaType(type, valueRequired);
-
- if (CurrentSchema.Type == JsonSchemaType.Integer && type.IsEnum && !type.IsDefined(typeof(FlagsAttribute), true))
+ switch (contract.ContractType)
{
- CurrentSchema.Enum = new List<JToken>();
- CurrentSchema.Options = new Dictionary<JToken, string>();
-
- EnumValues<long> enumValues = EnumUtils.GetNamesAndValues<long>(type);
- foreach (EnumValue<long> enumValue in enumValues)
- {
- JToken value = JToken.FromObject(enumValue.Value);
-
- CurrentSchema.Enum.Add(value);
- CurrentSchema.Options.Add(value, enumValue.Name);
- }
- }
- }
- else if (contract is JsonObjectContract)
- {
- CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
- CurrentSchema.Id = GetTypeId(type, false);
- GenerateObjectSchema(type, (JsonObjectContract)contract);
- }
+ case JsonContractType.Object:
+ CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
+ CurrentSchema.Id = GetTypeId(type, false);
+ GenerateObjectSchema(type, (JsonObjectContract) contract);
+ break;
+ case JsonContractType.Array:
+ CurrentSchema.Type = AddNullType(JsonSchemaType.Array, valueRequired);
+
+ CurrentSchema.Id = GetTypeId(type, false);
+
+ JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute;
+ bool allowNullItem = (arrayAttribute == null || arrayAttribute.AllowNullItems);
+
+ Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
+ if (collectionItemType != null)
+ {
+ CurrentSchema.Items = new List<JsonSchema>();
+ CurrentSchema.Items.Add(GenerateInternal(collectionItemType, (!allowNullItem) ? Required.Always : Required.Default, false));
+ }
+ break;
+ case JsonContractType.Primitive:
+ CurrentSchema.Type = GetJsonSchemaType(type, valueRequired);
+
+ if (CurrentSchema.Type == JsonSchemaType.Integer && type.IsEnum && !type.IsDefined(typeof (FlagsAttribute), true))
+ {
+ CurrentSchema.Enum = new List<JToken>();
+ CurrentSchema.Options = new Dictionary<JToken, string>();
+
+ EnumValues<long> enumValues = EnumUtils.GetNamesAndValues<long>(type);
+ foreach (EnumValue<long> enumValue in enumValues)
+ {
+ JToken value = JToken.FromObject(enumValue.Value);
+
+ CurrentSchema.Enum.Add(value);
+ CurrentSchema.Options.Add(value, enumValue.Name);
+ }
+ }
+ break;
+ case JsonContractType.String:
+ JsonSchemaType schemaType = (!ReflectionUtils.IsNullable(contract.UnderlyingType))
+ ? JsonSchemaType.String
+ : AddNullType(JsonSchemaType.String, valueRequired);
+
+ CurrentSchema.Type = schemaType;
+ break;
+ case JsonContractType.Dictionary:
+ CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
+
+ Type keyType;
+ Type valueType;
+ ReflectionUtils.GetDictionaryKeyValueTypes(type, out keyType, out valueType);
+
+ if (keyType != null)
+ {
+ // can be converted to a string
+ if (typeof (IConvertible).IsAssignableFrom(keyType))
+ {
+ CurrentSchema.AdditionalProperties = GenerateInternal(valueType, Required.Default, false);
+ }
+ }
+ break;
#if !SILVERLIGHT && !PocketPC
- else if (contract is JsonISerializableContract)
- {
- CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
- CurrentSchema.Id = GetTypeId(type, false);
- GenerateISerializableContract(type, (JsonISerializableContract) contract);
- }
+ case JsonContractType.Serializable:
+ CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
+ CurrentSchema.Id = GetTypeId(type, false);
+ GenerateISerializableContract(type, (JsonISerializableContract) contract);
+ break;
#endif
- else if (contract is JsonLinqContract)
- {
- CurrentSchema.Type = JsonSchemaType.Any;
- }
- else
- {
- throw new Exception("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract));
+ case JsonContractType.Dynamic:
+ case JsonContractType.Linq:
+ CurrentSchema.Type = JsonSchemaType.Any;
+ break;
+ default:
+ throw new Exception("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract));
+ }
}
return Pop().Schema;
diff --git a/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs b/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs
index 23db0c8..7fd8b74 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs
@@ -52,6 +52,8 @@ namespace Newtonsoft.Json.Serialization
public JsonArrayContract(Type underlyingType)
: base(underlyingType)
{
+ ContractType = JsonContractType.Array;
+
if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType))
{
CollectionItemType = _genericCollectionDefinitionType.GetGenericArguments()[0];
diff --git a/Src/Newtonsoft.Json/Serialization/JsonContract.cs b/Src/Newtonsoft.Json/Serialization/JsonContract.cs
index f8b1a4e..ef450b6 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonContract.cs
@@ -30,20 +30,44 @@ using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Serialization
{
+ internal enum JsonContractType
+ {
+ None,
+ Object,
+ Array,
+ Primitive,
+ String,
+ Dictionary,
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+ Dynamic,
+#endif
+#if !SILVERLIGHT && !PocketPC
+ Serializable,
+#endif
+ Linq
+ }
+
+ internal enum ReadType
+ {
+ Read,
+ ReadAsInt32,
+ ReadAsDecimal,
+ ReadAsBytes,
+#if !NET20
+ ReadAsDateTimeOffset
+#endif
+ }
+
/// <summary>
/// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
/// </summary>
public abstract class JsonContract
{
- internal enum ReadType
- {
- Read,
- ReadAsDecimal,
- ReadAsBytes,
-#if !NET20
- ReadAsDateTimeOffset
-#endif
- }
+ internal bool IsNullable;
+ internal bool IsConvertable;
+ internal Type NonNullableUnderlyingType;
+ internal ReadType InternalReadType;
+ internal JsonContractType ContractType;
/// <summary>
/// Gets the underlying type for the contract.
@@ -73,11 +97,6 @@ namespace Newtonsoft.Json.Serialization
// checked for after passed in converters and attribute specified converters
internal JsonConverter InternalConverter { get; set; }
- internal ReadType InternalReadType;
- internal bool IsNullable;
- internal bool IsConvertable;
- internal Type NonNullableUnderlyingType;
-
#if !PocketPC
/// <summary>
/// Gets or sets the method called immediately after deserialization of the object.
@@ -177,6 +196,10 @@ namespace Newtonsoft.Json.Serialization
{
InternalReadType = ReadType.ReadAsBytes;
}
+ else if (NonNullableUnderlyingType == typeof(int))
+ {
+ InternalReadType = ReadType.ReadAsInt32;
+ }
else if (NonNullableUnderlyingType == typeof(decimal))
{
InternalReadType = ReadType.ReadAsDecimal;
diff --git a/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs b/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
index 16c67fe..975c937 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
@@ -60,6 +60,8 @@ namespace Newtonsoft.Json.Serialization
public JsonDictionaryContract(Type underlyingType)
: base(underlyingType)
{
+ ContractType = JsonContractType.Dictionary;
+
Type keyType;
Type valueType;
if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IDictionary<,>), out _genericCollectionDefinitionType))
diff --git a/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs b/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs
index 75f08be..2645c3a 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs
@@ -56,6 +56,8 @@ namespace Newtonsoft.Json.Serialization
public JsonDynamicContract(Type underlyingType)
: base(underlyingType)
{
+ ContractType = JsonContractType.Dynamic;
+
Properties = new JsonPropertyCollection(UnderlyingType);
}
}
diff --git a/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs b/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs
index ee1eadb..c033f76 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs
@@ -50,6 +50,7 @@ namespace Newtonsoft.Json.Serialization
public JsonISerializableContract(Type underlyingType)
: base(underlyingType)
{
+ ContractType = JsonContractType.Serializable;
}
}
}
diff --git a/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs b/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs
index bc3526f..1f10088 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs
@@ -17,6 +17,7 @@ namespace Newtonsoft.Json.Serialization
public JsonLinqContract(Type underlyingType)
: base(underlyingType)
{
+ ContractType = JsonContractType.Linq;
}
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs b/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs
index 426a469..ef249c5 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs
@@ -44,10 +44,10 @@ namespace Newtonsoft.Json.Serialization
/// </summary>
/// <value>The object's properties.</value>
public JsonPropertyCollection Properties { get; private set; }
-
- /// <summary>
- /// Gets the constructor parameters required for any non-default constructor
- /// </summary>
+
+ /// <summary>
+ /// Gets the constructor parameters required for any non-default constructor
+ /// </summary>
public JsonPropertyCollection ConstructorParameters { get; private set; }
/// <summary>
@@ -71,8 +71,10 @@ namespace Newtonsoft.Json.Serialization
public JsonObjectContract(Type underlyingType)
: base(underlyingType)
{
- Properties = new JsonPropertyCollection(UnderlyingType);
- ConstructorParameters = new JsonPropertyCollection(UnderlyingType);
+ ContractType = JsonContractType.Object;
+
+ Properties = new JsonPropertyCollection(UnderlyingType);
+ ConstructorParameters = new JsonPropertyCollection(UnderlyingType);
}
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs b/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs
index 60bc83a..040613a 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs
@@ -39,6 +39,7 @@ namespace Newtonsoft.Json.Serialization
public JsonPrimitiveContract(Type underlyingType)
: base(underlyingType)
{
+ ContractType = JsonContractType.Primitive;
}
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
index cc1953b..a0f1d2f 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
@@ -64,7 +64,7 @@ namespace Newtonsoft.Json.Serialization
if (reader.TokenType == JsonToken.StartArray)
{
- if (contract is JsonArrayContract)
+ if (contract.ContractType == JsonContractType.Array)
PopulateList(CollectionUtils.CreateCollectionWrapper(target), reader, null, (JsonArrayContract) contract);
else
throw CreateSerializationException(reader, "Cannot populate JSON array onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
@@ -81,9 +81,9 @@ namespace Newtonsoft.Json.Serialization
CheckedRead(reader);
}
- if (contract is JsonDictionaryContract)
+ if (contract.ContractType == JsonContractType.Dictionary)
PopulateDictionary(CollectionUtils.CreateDictionaryWrapper(target), reader, (JsonDictionaryContract) contract, id);
- else if (contract is JsonObjectContract)
+ else if (contract.ContractType == JsonContractType.Object)
PopulateObject(target, reader, (JsonObjectContract) contract, id);
else
throw CreateSerializationException(reader, "Cannot populate JSON object onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
@@ -223,7 +223,7 @@ namespace Newtonsoft.Json.Serialization
private object CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue)
{
- if (contract is JsonLinqContract)
+ if (contract != null && contract.ContractType == JsonContractType.Linq)
return CreateJToken(reader, contract);
do
@@ -425,53 +425,43 @@ namespace Newtonsoft.Json.Serialization
if (contract == null)
throw CreateSerializationException(reader, "Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType));
- JsonDictionaryContract dictionaryContract = contract as JsonDictionaryContract;
- if (dictionaryContract != null)
+ switch (contract.ContractType)
{
- if (existingValue == null)
- return CreateAndPopulateDictionary(reader, dictionaryContract, id);
-
- return PopulateDictionary(dictionaryContract.CreateWrapper(existingValue), reader, dictionaryContract, id);
- }
-
- JsonObjectContract objectContract = contract as JsonObjectContract;
- if (objectContract != null)
- {
- if (existingValue == null)
- return CreateAndPopulateObject(reader, objectContract, id);
-
- return PopulateObject(existingValue, reader, objectContract, id);
- }
-
- JsonPrimitiveContract primitiveContract = contract as JsonPrimitiveContract;
- if (primitiveContract != null)
- {
- // if the content is inside $value then read past it
- if (reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), JsonTypeReflector.ValuePropertyName, StringComparison.Ordinal))
- {
- CheckedRead(reader);
- object value = CreateValueInternal(reader, objectType, primitiveContract, member, existingValue);
+ case JsonContractType.Object:
+ JsonObjectContract objectContract = (JsonObjectContract) contract;
+ if (existingValue == null)
+ return CreateAndPopulateObject(reader, objectContract, id);
+
+ return PopulateObject(existingValue, reader, objectContract, id);
+ case JsonContractType.Primitive:
+ JsonPrimitiveContract primitiveContract = (JsonPrimitiveContract) contract;
+ // if the content is inside $value then read past it
+ if (reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), JsonTypeReflector.ValuePropertyName, StringComparison.Ordinal))
+ {
+ CheckedRead(reader);
+ object value = CreateValueInternal(reader, objectType, primitiveContract, member, existingValue);
- CheckedRead(reader);
- return value;
- }
- }
+ CheckedRead(reader);
+ return value;
+ }
+ break;
+ case JsonContractType.Dictionary:
+ JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) contract;
+ if (existingValue == null)
+ return CreateAndPopulateDictionary(reader, dictionaryContract, id);
+ return PopulateDictionary(dictionaryContract.CreateWrapper(existingValue), reader, dictionaryContract, id);
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+ case JsonContractType.Dynamic:
+ JsonDynamicContract dynamicContract = (JsonDynamicContract) contract;
+ return CreateDynamic(reader, dynamicContract, id);
+#endif
#if !SILVERLIGHT && !PocketPC
- JsonISerializableContract serializableContract = contract as JsonISerializableContract;
- if (serializableContract != null)
- {
- return CreateISerializable(reader, serializableContract, id);
- }
+ case JsonContractType.Serializable:
+ JsonISerializableContract serializableContract = (JsonISerializableContract) contract;
+ return CreateISerializable(reader, serializableContract, id);
#endif
-
-#if !(NET35 || NET20 || WINDOWS_PHONE)
- JsonDynamicContract dynamicContract = contract as JsonDynamicContract;
- if (dynamicContract != null)
- {
- return CreateDynamic(reader, dynamicContract, id);
}
-#endif
throw CreateSerializationException(reader, "Cannot deserialize JSON object into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
}
@@ -1009,7 +999,7 @@ namespace Newtonsoft.Json.Serialization
// handle readonly collection/dictionary properties
JsonContract propertyContract = Serializer.ContractResolver.ResolveContract(property.PropertyType);
- if (propertyContract is JsonArrayContract)
+ if (propertyContract.ContractType == JsonContractType.Array)
{
JsonArrayContract propertyArrayContract = propertyContract as JsonArrayContract;
@@ -1025,7 +1015,7 @@ namespace Newtonsoft.Json.Serialization
}
}
}
- else if (propertyContract is JsonDictionaryContract)
+ else if (propertyContract.ContractType == JsonContractType.Dictionary)
{
JsonDictionaryContract jsonDictionaryContract = propertyContract as JsonDictionaryContract;
@@ -1116,11 +1106,11 @@ namespace Newtonsoft.Json.Serialization
if (hasConverter)
return reader.Read();
- JsonContract.ReadType t = (contract != null) ? contract.InternalReadType : JsonContract.ReadType.Read;
+ ReadType t = (contract != null) ? contract.InternalReadType : ReadType.Read;
switch (t)
{
- case JsonContract.ReadType.Read:
+ case ReadType.Read:
do
{
if (!reader.Read())
@@ -1128,20 +1118,26 @@ namespace Newtonsoft.Json.Serialization
} while (reader.TokenType == JsonToken.Comment);
return true;
- case JsonContract.ReadType.ReadAsDecimal:
+ case ReadType.ReadAsInt32:
+ SetSerializeInArray(reader, inArray, true);
+ reader.ReadAsInt32();
+ SetSerializeInArray(reader, inArray, false);
+
+ return true;
+ case ReadType.ReadAsDecimal:
SetSerializeInArray(reader, inArray, true);
reader.ReadAsDecimal();
SetSerializeInArray(reader, inArray, false);
return true;
- case JsonContract.ReadType.ReadAsBytes:
+ case ReadType.ReadAsBytes:
SetSerializeInArray(reader, inArray, true);
reader.ReadAsBytes();
SetSerializeInArray(reader, inArray, false);
return true;
#if !NET20
- case JsonContract.ReadType.ReadAsDateTimeOffset:
+ case ReadType.ReadAsDateTimeOffset:
SetSerializeInArray(reader, inArray, true);
reader.ReadAsDateTimeOffset();
SetSerializeInArray(reader, inArray, false);
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
index 5ac8dcd..a77f83c 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
@@ -105,58 +105,55 @@ namespace Newtonsoft.Json.Serialization
}
if ((converter != null
- || ((converter = valueContract.Converter) != null)
- || ((converter = Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null)
- || ((converter = valueContract.InternalConverter) != null))
- && converter.CanWrite)
+ || ((converter = valueContract.Converter) != null)
+ || ((converter = Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null)
+ || ((converter = valueContract.InternalConverter) != null))
+ && converter.CanWrite)
{
SerializeConvertable(writer, converter, value, valueContract);
+ return;
}
- else if (valueContract is JsonStringContract)
- {
- SerializeString(writer, value, (JsonStringContract)valueContract);
- }
- else if (valueContract is JsonPrimitiveContract)
- {
- SerializePrimitive(writer, value, (JsonPrimitiveContract)valueContract, member, collectionValueContract);
- }
- else if (valueContract is JsonObjectContract)
- {
- SerializeObject(writer, value, (JsonObjectContract)valueContract, member, collectionValueContract);
- }
- else if (valueContract is JsonDictionaryContract)
- {
- JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)valueContract;
- SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member, collectionValueContract);
- }
- else if (valueContract is JsonArrayContract)
- {
- JsonArrayContract arrayContract = (JsonArrayContract)valueContract;
- SerializeList(writer, arrayContract.CreateWrapper(value), arrayContract, member, collectionValueContract);
- }
- else if (valueContract is JsonLinqContract)
- {
- ((JToken)value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null);
- }
+
+ switch (valueContract.ContractType)
+ {
+ case JsonContractType.Object:
+ SerializeObject(writer, value, (JsonObjectContract) valueContract, member, collectionValueContract);
+ break;
+ case JsonContractType.Array:
+ JsonArrayContract arrayContract = (JsonArrayContract) valueContract;
+ SerializeList(writer, arrayContract.CreateWrapper(value), arrayContract, member, collectionValueContract);
+ break;
+ case JsonContractType.Primitive:
+ SerializePrimitive(writer, value, (JsonPrimitiveContract) valueContract, member, collectionValueContract);
+ break;
+ case JsonContractType.String:
+ SerializeString(writer, value, (JsonStringContract) valueContract);
+ break;
+ case JsonContractType.Dictionary:
+ JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) valueContract;
+ SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member, collectionValueContract);
+ break;
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+ case JsonContractType.Dynamic:
+ SerializeDynamic(writer, (IDynamicMetaObjectProvider) value, (JsonDynamicContract) valueContract);
+ break;
+#endif
#if !SILVERLIGHT && !PocketPC
- else if (valueContract is JsonISerializableContract)
- {
- SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract, member, collectionValueContract);
- }
+ case JsonContractType.Serializable:
+ SerializeISerializable(writer, (ISerializable) value, (JsonISerializableContract) valueContract, member, collectionValueContract);
+ break;
#endif
-#if !(NET35 || NET20 || WINDOWS_PHONE)
- else if (valueContract is JsonDynamicContract)
- {
- SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract);
+ case JsonContractType.Linq:
+ ((JToken) value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null);
+ break;
}
-#endif
}
private bool ShouldWriteReference(object value, JsonProperty property, JsonContract contract)
{
if (value == null)
return false;
- if (contract is JsonPrimitiveContract)
+ if (contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String)
return false;
bool? isReference = null;
@@ -170,7 +167,7 @@ namespace Newtonsoft.Json.Serialization
if (isReference == null)
{
- if (contract is JsonArrayContract)
+ if (contract.ContractType == JsonContractType.Array)
isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
else
isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
@@ -214,7 +211,7 @@ namespace Newtonsoft.Json.Serialization
private bool CheckForCircularReference(object value, ReferenceLoopHandling? referenceLoopHandling, JsonContract contract)
{
- if (value == null || contract is JsonPrimitiveContract)
+ if (value == null || contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String)
return true;
if (_serializeStack.IndexOf(value) != -1)
diff --git a/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs b/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs
index c608d9e..b76925e 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs
@@ -42,6 +42,7 @@ namespace Newtonsoft.Json.Serialization
public JsonStringContract(Type underlyingType)
: base(underlyingType)
{
+ ContractType = JsonContractType.String;
}
}
} \ No newline at end of file