-Added DateTimeKindHandling to BsonWriter to control how a DateTime is converted prior to being serialized

-Added Required.Always attribute validation when writing JSON as well reading
-Added TypeNameHandling.Auto to automatically write the type name when a value doesn't match the declared type
-Fixed reading multi-byte strings in BSON
This commit is contained in:
JamesNK
2010-07-03 09:53:57 +00:00
parent c9ec228942
commit c2800930ab
12 changed files with 237 additions and 91 deletions
@@ -558,5 +558,45 @@ namespace Newtonsoft.Json.Tests.Bson
Assert.IsFalse(reader.Read());
}
[Test]
public void WriteDateTimes()
{
MemoryStream ms = new MemoryStream();
BsonWriter writer = new BsonWriter(ms);
writer.DateTimeKindHandling = DateTimeKind.Unspecified;
writer.WriteStartArray();
writer.WriteValue(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc));
writer.WriteValue(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Local));
writer.WriteValue(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Unspecified));
writer.WriteEndArray();
ms.Seek(0, SeekOrigin.Begin);
BsonReader reader = new BsonReader(ms);
reader.ReadRootValueAsArray = true;
reader.DateTimeKindHandling = DateTimeKind.Utc;
Assert.IsTrue(reader.Read());
Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
Assert.IsTrue(reader.Read());
Assert.AreEqual(JsonToken.Date, reader.TokenType);
Assert.AreEqual(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc), reader.Value);
Assert.IsTrue(reader.Read());
Assert.AreEqual(JsonToken.Date, reader.TokenType);
Assert.AreEqual(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc), reader.Value);
Assert.IsTrue(reader.Read());
Assert.AreEqual(JsonToken.Date, reader.TokenType);
Assert.AreEqual(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc), reader.Value);
Assert.IsTrue(reader.Read());
Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
Assert.IsFalse(reader.Read());
}
}
}
@@ -34,8 +34,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;
#region Data
private const string BsonHex =
@@ -508,7 +508,7 @@ namespace Newtonsoft.Json.Tests
TimeOperation<object>(() =>
{
for (int i = 0; i < 5000; i++)
for (int i = 0; i < Iterations; i++)
{
test["dummy"] = new JValue(i);
Encoding.UTF8.GetBytes(test.ToString(Formatting.None));
@@ -526,7 +526,7 @@ namespace Newtonsoft.Json.Tests
TimeOperation<object>(() =>
{
for (int i = 0; i < 5000; i++)
for (int i = 0; i < Iterations; i++)
{
test["dummy"] = new JValue(i);
ms.Seek(0, SeekOrigin.Begin);
@@ -1012,7 +1012,7 @@ keyword such as type of business.""
}
[Test]
public void RequiredMembersClassWithNullValues()
public void DeserializeRequiredMembersClassWithNullValues()
{
string json = @"{
""FirstName"": ""I can't be null bro!"",
@@ -1030,7 +1030,7 @@ keyword such as type of business.""
[Test]
[ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Required property 'FirstName' expects a value but got null.")]
public void RequiredMembersClassNullRequiredValueProperty()
public void DeserializeRequiredMembersClassNullRequiredValueProperty()
{
string json = @"{
""FirstName"": null,
@@ -1042,6 +1042,22 @@ keyword such as type of business.""
JsonConvert.DeserializeObject<RequiredMembersClass>(json);
}
[Test]
[ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Cannot write a null value for property 'FirstName'. Property requires a value.")]
public void SerializeRequiredMembersClassNullRequiredValueProperty()
{
RequiredMembersClass requiredMembersClass = new RequiredMembersClass
{
FirstName = null,
BirthDate = new DateTime(2000, 10, 10, 10, 10, 10, DateTimeKind.Utc),
LastName = null,
MiddleName = null
};
string json = JsonConvert.SerializeObject(requiredMembersClass);
Console.WriteLine(json);
}
[Test]
[ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Required property 'LastName' not found in JSON.")]
public void RequiredMembersClassMissingRequiredProperty()
@@ -461,60 +461,82 @@ namespace Newtonsoft.Json.Tests.Serialization
}
#endif
//[Test]
//[Ignore("TODO")]
//public void CollectionWithAbstractItems()
//{
// string Text = "";
[Test]
public void CollectionWithAbstractItems()
{
HolderClass testObject = new HolderClass();
testObject.TestMember = new ContentSubClass("First One");
testObject.AnotherTestMember = new Dictionary<int, IList<ContentBaseClass>>();
testObject.AnotherTestMember.Add(1, new List<ContentBaseClass>());
testObject.AnotherTestMember[1].Add(new ContentSubClass("Second One"));
testObject.AThirdTestMember = new ContentSubClass("Third One");
// HolderClass testObject = new HolderClass();
// testObject.TestMember = new ContentSubClass("First One");
// testObject.AnotherTestMember = new Dictionary<int, List<ContentBaseClass>>();
// testObject.AnotherTestMember.Add(1, new List<ContentBaseClass>());
// testObject.AnotherTestMember[1].Add(new ContentSubClass("Second One"));
// testObject.AThirdTestMember = new ContentSubClass("Third One");
// HolderClass anotherTestObject = null;
JsonSerializer serializingTester = new JsonSerializer();
serializingTester.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
// Newtonsoft.Json.JsonSerializer serializingTester = new Newtonsoft.Json.JsonSerializer();
// serializingTester.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
StringWriter sw = new StringWriter();
using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
serializingTester.TypeNameHandling = TypeNameHandling.Auto;
serializingTester.Serialize(jsonWriter, testObject);
}
// StringWriter sw = new StringWriter();
// using (Newtonsoft.Json.JsonTextWriter jsonWriter = new Newtonsoft.Json.JsonTextWriter(sw))
// {
// jsonWriter.Formatting = Newtonsoft.Json.Formatting.Indented;
string json = sw.ToString();
// if (Text.Equals("Properties All, Serializer All"))
// serializingTester.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All;
// else if (Text.Equals("Properties All, Serializer Objects"))
// serializingTester.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Objects;
// else if (Text.Equals("Properties All, Serializer Arrays"))
// serializingTester.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Arrays;
// //otherwise leave default, which looks like it's "None"
string contentSubClassRef = ReflectionUtils.GetTypeName(typeof(ContentSubClass), FormatterAssemblyStyle.Simple);
string dictionaryRef = ReflectionUtils.GetTypeName(typeof(Dictionary<int, IList<ContentBaseClass>>), FormatterAssemblyStyle.Simple);
string listRef = ReflectionUtils.GetTypeName(typeof(List<ContentBaseClass>), FormatterAssemblyStyle.Simple);
// serializingTester.Serialize(jsonWriter, testObject);
// }
// string json = sw.ToString();
Assert.AreEqual(@"{
""TestMember"": {
""$type"": """ + contentSubClassRef + @""",
""SomeString"": ""First One""
},
""AnotherTestMember"": {
""$type"": """ + dictionaryRef + @""",
""1"": {
""$type"": """ + listRef + @""",
""$values"": [
{
""$type"": """ + contentSubClassRef + @""",
""SomeString"": ""Second One""
}
]
}
},
""AThirdTestMember"": {
""$type"": """ + contentSubClassRef + @""",
""SomeString"": ""Third One""
}
}", json);
Console.WriteLine(json);
// Console.WriteLine(json);
StringReader sr = new StringReader(json);
// StringReader sr = new StringReader(json);
JsonSerializer deserializingTester = new JsonSerializer();
// Newtonsoft.Json.JsonSerializer deserializingTester = new Newtonsoft.Json.JsonSerializer();
HolderClass anotherTestObject;
// using (Newtonsoft.Json.JsonTextReader jsonReader = new Newtonsoft.Json.JsonTextReader(sr))
// {
// if (Text.Equals("Properties All, Serializer All"))
// deserializingTester.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All;
// else if (Text.Equals("Properties All, Serializer Objects"))
// deserializingTester.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Objects;
// else if (Text.Equals("Properties All, Serializer Arrays"))
// deserializingTester.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Arrays;
// //otherwise leave default, which looks like it's "None"
using (JsonTextReader jsonReader = new JsonTextReader(sr))
{
deserializingTester.TypeNameHandling = TypeNameHandling.Auto;
// anotherTestObject = deserializingTester.Deserialize<HolderClass>(jsonReader);
// }
//}
anotherTestObject = deserializingTester.Deserialize<HolderClass>(jsonReader);
}
Assert.IsNotNull(anotherTestObject);
Assert.IsInstanceOfType(typeof(ContentSubClass), anotherTestObject.TestMember);
Assert.IsInstanceOfType(typeof(Dictionary<int, IList<ContentBaseClass>>), anotherTestObject.AnotherTestMember);
Assert.AreEqual(1, anotherTestObject.AnotherTestMember.Count);
IList<ContentBaseClass> list = anotherTestObject.AnotherTestMember[1];
Assert.IsInstanceOfType(typeof(List<ContentBaseClass>), list);
Assert.AreEqual(1, list.Count);
Assert.IsInstanceOfType(typeof(ContentSubClass), list[0]);
}
}
}
@@ -13,7 +13,7 @@ namespace Newtonsoft.Json.Tests.TestObjects
public ContentBaseClass TestMember { get; set; }
[Newtonsoft.Json.JsonProperty(TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All)]
public Dictionary<int, List<ContentBaseClass>> AnotherTestMember { get; set; }
public Dictionary<int, IList<ContentBaseClass>> AnotherTestMember { get; set; }
public ContentBaseClass AThirdTestMember { get; set; }
+9 -2
View File
@@ -17,8 +17,11 @@ namespace Newtonsoft.Json.Bson
private byte[] _largeByteBuffer;
private int _maxChars;
public DateTimeKind DateTimeKindHandling { get; set; }
public BsonBinaryWriter(Stream stream)
{
DateTimeKindHandling = DateTimeKind.Utc;
_writer = new BinaryWriter(stream);
}
@@ -107,8 +110,12 @@ namespace Newtonsoft.Json.Bson
if (value.Value is DateTime)
{
DateTime dateTime = (DateTime) value.Value;
dateTime = dateTime.ToUniversalTime();
ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(dateTime);
if (DateTimeKindHandling == DateTimeKind.Utc)
dateTime = dateTime.ToUniversalTime();
else if (DateTimeKindHandling == DateTimeKind.Local)
dateTime = dateTime.ToLocalTime();
ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(dateTime, false);
}
#if !PocketPC && !NET20
else
+8 -6
View File
@@ -572,23 +572,27 @@ namespace Newtonsoft.Json.Bson
StringBuilder builder = null;
int totalBytesRead = 0;
// used in case of left over multibyte characters in the buffer
int offset = 0;
do
{
// read up to the maximum size of the buffer or what is remaining, minus the offset
// of left over multibyte chars
int count = ((length - totalBytesRead) > MaxCharBytesSize - offset)
? MaxCharBytesSize - offset
: length - totalBytesRead - offset;
: length - totalBytesRead;
int byteCount = _reader.BaseStream.Read(_byteBuffer, offset, count);
if (byteCount == 0)
throw new EndOfStreamException("Unable to read beyond the end of the stream.");
totalBytesRead += byteCount;
// Above, byteCount is how many bytes we read this time.
// Below, byteCount is how many bytes are in the _byteBuffer.
byteCount += offset;
if (totalBytesRead == 0 && byteCount == length)
if (byteCount == length)
{
// pref optimization to avoid reading into a string builder
// first iteration and all bytes read then return string directly
@@ -615,8 +619,6 @@ namespace Newtonsoft.Json.Bson
{
offset = 0;
}
totalBytesRead += (byteCount - offset);
}
}
while (totalBytesRead < length);
+11
View File
@@ -45,6 +45,17 @@ namespace Newtonsoft.Json.Bson
private BsonToken _parent;
private string _propertyName;
/// <summary>
/// Gets or sets the <see cref="DateTimeKind" /> used when writing <see cref="DateTime"/> values to BSON.
/// When set to <see cref="DateTimeKind.Unspecified" /> no conversion will occur.
/// </summary>
/// <value>The <see cref="DateTimeKind" /> used when writing <see cref="DateTime"/> values to BSON.</value>
public DateTimeKind DateTimeKindHandling
{
get { return _writer.DateTimeKindHandling; }
set { _writer.DateTimeKindHandling = value; }
}
/// <summary>
/// Initializes a new instance of the <see cref="BsonWriter"/> class.
/// </summary>
+7 -2
View File
@@ -181,9 +181,14 @@ namespace Newtonsoft.Json
internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime)
{
long universialTicks = ToUniversalTicks(dateTime);
return ConvertDateTimeToJavaScriptTicks(dateTime, true);
}
return UniversialTicksToJavaScriptTicks(universialTicks);
internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, bool convertToUtc)
{
long ticks = (convertToUtc) ? ToUniversalTicks(dateTime) : dateTime.Ticks;
return UniversialTicksToJavaScriptTicks(ticks);
}
private static long UniversialTicksToJavaScriptTicks(long universialTicks)
+1 -1
View File
@@ -109,7 +109,7 @@ namespace Newtonsoft.Json
get { return _typeNameHandling; }
set
{
if (value < TypeNameHandling.None || value > TypeNameHandling.All)
if (value < TypeNameHandling.None || value > TypeNameHandling.Auto)
throw new ArgumentOutOfRangeException("value");
_typeNameHandling = value;
@@ -62,7 +62,7 @@ namespace Newtonsoft.Json.Serialization
if (jsonWriter == null)
throw new ArgumentNullException("jsonWriter");
SerializeValue(jsonWriter, value, null, GetContractSafe(value));
SerializeValue(jsonWriter, value, GetContractSafe(value), null, null);
}
private JsonSerializerProxy GetInternalSerializer()
@@ -81,7 +81,7 @@ namespace Newtonsoft.Json.Serialization
return Serializer.ContractResolver.ResolveContract(value.GetType());
}
private void SerializeValue(JsonWriter writer, object value, JsonProperty member, JsonContract contract)
private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContract collectionValueContract)
{
JsonConverter converter = (member != null) ? member.Converter : null;
@@ -92,39 +92,39 @@ namespace Newtonsoft.Json.Serialization
}
if ((converter != null
|| ((converter = contract.Converter) != null)
|| ((converter = Serializer.GetMatchingConverter(contract.UnderlyingType)) != null)
|| ((converter = contract.InternalConverter) != null))
|| ((converter = valueContract.Converter) != null)
|| ((converter = Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null)
|| ((converter = valueContract.InternalConverter) != null))
&& converter.CanWrite)
{
SerializeConvertable(writer, converter, value, contract);
SerializeConvertable(writer, converter, value, valueContract);
}
else if (contract is JsonPrimitiveContract)
else if (valueContract is JsonPrimitiveContract)
{
writer.WriteValue(value);
}
else if (contract is JsonStringContract)
else if (valueContract is JsonStringContract)
{
SerializeString(writer, value, (JsonStringContract) contract);
SerializeString(writer, value, (JsonStringContract) valueContract);
}
else if (contract is JsonObjectContract)
else if (valueContract is JsonObjectContract)
{
SerializeObject(writer, value, (JsonObjectContract) contract, member);
SerializeObject(writer, value, (JsonObjectContract)valueContract, member, collectionValueContract);
}
else if (contract is JsonDictionaryContract)
else if (valueContract is JsonDictionaryContract)
{
JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) contract;
SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member);
JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) valueContract;
SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member, collectionValueContract);
}
else if (contract is JsonArrayContract)
else if (valueContract is JsonArrayContract)
{
if (value is IList)
{
SerializeList(writer, (IList) value, (JsonArrayContract) contract, member);
SerializeList(writer, (IList)value, (JsonArrayContract)valueContract, member, collectionValueContract);
}
else if (value is IEnumerable)
{
SerializeList(writer, ((IEnumerable)value).Cast<object>().ToList(), (JsonArrayContract)contract, member);
SerializeList(writer, ((IEnumerable)value).Cast<object>().ToList(), (JsonArrayContract)valueContract, member, collectionValueContract);
}
else
{
@@ -133,14 +133,14 @@ namespace Newtonsoft.Json.Serialization
CultureInfo.InvariantCulture, value.GetType()));
}
}
else if (contract is JsonLinqContract)
else if (valueContract is JsonLinqContract)
{
((JToken)value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null);
}
#if !SILVERLIGHT && !PocketPC
else if (contract is JsonISerializableContract)
else if (valueContract is JsonISerializableContract)
{
SerializeISerializable(writer, (ISerializable) value, (JsonISerializableContract) contract);
SerializeISerializable(writer, (ISerializable) value, (JsonISerializableContract) valueContract);
}
#endif
}
@@ -198,8 +198,11 @@ namespace Newtonsoft.Json.Serialization
if (!CheckForCircularReference(memberValue, property.ReferenceLoopHandling, contract))
return;
if (memberValue == null && property.Required == Required.Always)
throw new JsonSerializationException("Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName));
writer.WritePropertyName(propertyName);
SerializeValue(writer, memberValue, property, contract);
SerializeValue(writer, memberValue, contract, property, null);
}
private bool CheckForCircularReference(object value, ReferenceLoopHandling? referenceLoopHandling, JsonContract contract)
@@ -286,7 +289,7 @@ namespace Newtonsoft.Json.Serialization
contract.InvokeOnSerialized(value, Serializer.Context);
}
private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member)
private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContract collectionValueContract)
{
contract.InvokeOnSerializing(value, Serializer.Context);
@@ -299,7 +302,7 @@ namespace Newtonsoft.Json.Serialization
writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
writer.WriteValue(Serializer.ReferenceResolver.GetReference(value));
}
if (HasFlag(((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling, TypeNameHandling.Objects))
if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionValueContract))
{
WriteTypeProperty(writer, contract.UnderlyingType);
}
@@ -368,14 +371,14 @@ namespace Newtonsoft.Json.Serialization
}
}
private void SerializeList(JsonWriter writer, IList values, JsonArrayContract contract, JsonProperty member)
private void SerializeList(JsonWriter writer, IList values, JsonArrayContract contract, JsonProperty member, JsonContract collectionValueContract)
{
contract.InvokeOnSerializing(values, Serializer.Context);
SerializeStack.Add(values);
bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
bool includeTypeDetails = HasFlag(((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling, TypeNameHandling.Arrays);
bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Arrays, contract, member, collectionValueContract);
if (isReference || includeTypeDetails)
{
@@ -393,6 +396,8 @@ namespace Newtonsoft.Json.Serialization
writer.WritePropertyName(JsonTypeReflector.ArrayValuesPropertyName);
}
JsonContract childValuesContract = Serializer.ContractResolver.ResolveContract(contract.CollectionItemType ?? typeof(object));
writer.WriteStartArray();
int initialDepth = writer.Top;
@@ -413,7 +418,7 @@ namespace Newtonsoft.Json.Serialization
if (!CheckForCircularReference(value, null, contract))
continue;
SerializeValue(writer, value, null, valueContract);
SerializeValue(writer, value, valueContract, null, childValuesContract);
}
}
catch (Exception ex)
@@ -451,7 +456,7 @@ namespace Newtonsoft.Json.Serialization
foreach (SerializationEntry serializationEntry in serializationInfo)
{
writer.WritePropertyName(serializationEntry.Name);
SerializeValue(writer, serializationEntry.Value, null, GetContractSafe(serializationEntry.Value));
SerializeValue(writer, serializationEntry.Value, GetContractSafe(serializationEntry.Value), null, null);
}
writer.WriteEndObject();
@@ -461,7 +466,39 @@ namespace Newtonsoft.Json.Serialization
}
#endif
private void SerializeDictionary(JsonWriter writer, IWrappedDictionary values, JsonDictionaryContract contract, JsonProperty member)
//private bool ShouldWriteTypeProperty(JsonProperty member, JsonContract contract, TypeNameHandling typeFlag)
//{
// if (HasFlag(((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling, typeFlag))
// return true;
// if ((((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling) == TypeNameHandling.Auto)
// || (member != null
// && (member.TypeNameHandling ?? Serializer.TypeNameHandling) == TypeNameHandling.Auto
// && contract.UnderlyingType != member.PropertyType)
// )
//}
private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty member, JsonContract collectionValueContract)
{
if (HasFlag(((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling, typeNameHandlingFlag))
return true;
if (member != null)
{
if ((member.TypeNameHandling ?? Serializer.TypeNameHandling) == TypeNameHandling.Auto && contract.UnderlyingType != member.PropertyType)
return true;
}
else if (collectionValueContract != null)
{
if (Serializer.TypeNameHandling == TypeNameHandling.Auto && contract.UnderlyingType != collectionValueContract.UnderlyingType)
return true;
}
return false;
}
private void SerializeDictionary(JsonWriter writer, IWrappedDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContract collectionValueContract)
{
contract.InvokeOnSerializing(values.UnderlyingDictionary, Serializer.Context);
@@ -474,11 +511,13 @@ namespace Newtonsoft.Json.Serialization
writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
writer.WriteValue(Serializer.ReferenceResolver.GetReference(values.UnderlyingDictionary));
}
if (HasFlag(((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling, TypeNameHandling.Objects))
if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionValueContract))
{
WriteTypeProperty(writer, values.UnderlyingDictionary.GetType());
}
JsonContract childValuesContract = Serializer.ContractResolver.ResolveContract(contract.DictionaryValueType ?? typeof(object));
int initialDepth = writer.Top;
// Mono Unity 3.0 fix
@@ -505,7 +544,7 @@ namespace Newtonsoft.Json.Serialization
writer.WritePropertyName(propertyName);
SerializeValue(writer, value, null, valueContract);
SerializeValue(writer, value, valueContract, null, childValuesContract);
}
}
catch (Exception ex)
+4
View File
@@ -24,6 +24,10 @@ namespace Newtonsoft.Json
/// </summary>
Arrays = 2,
/// <summary>
/// Include the .NET type name when the type of the object being serialized is not the same as its declared type.
/// </summary>
Auto = 4,
/// <summary>
/// Always include the .NET type name when serializing.
/// </summary>
All = Objects | Arrays