-Improved default null and value handing when JSON value is not compatible with property value

-Added interfaces, structs and enums as valid targets of JsonConverterAttribute
This commit is contained in:
JamesNK
2010-05-27 08:37:34 +00:00
parent fc6c041196
commit f5ed7be283
7 changed files with 59 additions and 4 deletions
@@ -35,6 +35,20 @@ namespace Newtonsoft.Json.Tests.Serialization
{
public class NullValueHandlingTests : TestFixtureBase
{
[Test]
public void DeserializeNullIntoDateTime()
{
DateTimeTestClass c = JsonConvert.DeserializeObject<DateTimeTestClass>(@"{DateTimeField:null}", new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
Assert.AreEqual(c.DateTimeField, default(DateTime));
}
[Test]
public void DeserializeEmptyStringIntoDateTimeWithEmptyStringDefaultValue()
{
DateTimeTestClass c = JsonConvert.DeserializeObject<DateTimeTestClass>(@"{DateTimeField:""""}", new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
Assert.AreEqual(c.DateTimeField, default(DateTime));
}
[Test]
public void NullValueHandlingSerialization()
{
@@ -26,6 +26,7 @@
#if !PocketPC && !NET20
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
@@ -34,6 +35,8 @@ namespace Newtonsoft.Json.Tests.TestObjects
public class DateTimeTestClass
{
public string PreField { get; set; }
[DefaultValue("")]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public DateTime DateTimeField { get; set; }
public DateTimeOffset DateTimeOffsetField { get; set; }
public string PostField { get; set; }
+2
View File
@@ -575,6 +575,8 @@ namespace Newtonsoft.Json.Bson
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;
+2 -2
View File
@@ -36,11 +36,11 @@ namespace Newtonsoft.Json
public enum DefaultValueHandling
{
/// <summary>
/// Include null values when serializing and deserializing objects.
/// Include default values when serializing and deserializing objects.
/// </summary>
Include = 0,
/// <summary>
/// Ignore null values when serializing and deserializing objects.
/// Ignore default values when serializing and deserializing objects.
/// </summary>
Ignore = 1
}
+18
View File
@@ -336,6 +336,24 @@ namespace Newtonsoft.Json
}
}
internal static bool IsPrimitiveToken(JsonToken token)
{
switch (token)
{
case JsonToken.Integer:
case JsonToken.Float:
case JsonToken.String:
case JsonToken.Boolean:
case JsonToken.Undefined:
case JsonToken.Null:
case JsonToken.Date:
case JsonToken.Bytes:
return true;
default:
return false;
}
}
internal static bool IsStartToken(JsonToken token)
{
switch (token)
@@ -125,8 +125,10 @@ namespace Newtonsoft.Json.Serialization
/// Initializes a new instance of the <see cref="DefaultContractResolver"/> class.
/// </summary>
/// <param name="shareCache">
/// if set to <c>true</c> the <see cref="IContractResolver"/> will use a cached shared with other resolvers of the same type.
/// This will improve significantly performance for unshared resolvers but cause unexpected behavior if instances of the resolver could produce different results.
/// If set to <c>true</c> the <see cref="DefaultContractResolver"/> will use a cached shared with other resolvers of the same type.
/// Sharing the cache will significantly performance because expensive reflection will only happen once but could 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 <see cref="DefaultContractResolver"/> instances with the <see cref="JsonSerializer"/>.
/// </param>
public DefaultContractResolver(bool shareCache)
{
@@ -510,6 +510,22 @@ namespace Newtonsoft.Json.Serialization
return;
}
// test tokentype here because null might not be convertable to some types, e.g. ignoring null when applied to DateTime
if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore && reader.TokenType == JsonToken.Null)
{
reader.Skip();
return;
}
// test tokentype here because default value might not be convertable to actual type, e.g. default of "" for DateTime
if (property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling) == DefaultValueHandling.Ignore
&& JsonReader.IsPrimitiveToken(reader.TokenType)
&& Equals(reader.Value, property.DefaultValue))
{
reader.Skip();
return;
}
object existingValue = (useExistingValue) ? currentValue : null;
object value = CreateValueProperty(reader, property, target, gottenCurrentValue, existingValue);