-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:
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user