* Apply fix to #1460 to async writing. * Replace recursion with iteration. * Test for 1460 in async use. * Change infinite loop style.
This commit is contained in:
committed by
James Newton-King
parent
3ea750d6d6
commit
1b40ebfe26
@@ -30,6 +30,10 @@ using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
#if !(NET20 || NET35 || NET40 || PORTABLE40)
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Xml;
|
||||
@@ -60,5 +64,17 @@ namespace Newtonsoft.Json.Tests.Issues
|
||||
|
||||
Assert.AreEqual("null", sw.ToString());
|
||||
}
|
||||
|
||||
#if !(NET20 || NET35 || NET40 || PORTABLE40)
|
||||
[Test]
|
||||
public async Task TestAsync()
|
||||
{
|
||||
StringWriter sw = new StringWriter();
|
||||
JsonTextWriter writer = new JsonTextWriter(sw);
|
||||
await JsonWriter.WriteValueAsync(writer, PrimitiveTypeCode.Object, null, CancellationToken.None);
|
||||
|
||||
Assert.AreEqual("null", sw.ToString());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1680,114 +1680,122 @@ namespace Newtonsoft.Json
|
||||
|
||||
internal static Task WriteValueAsync(JsonWriter writer, PrimitiveTypeCode typeCode, object value, CancellationToken cancellationToken)
|
||||
{
|
||||
switch (typeCode)
|
||||
while (true)
|
||||
{
|
||||
case PrimitiveTypeCode.Char:
|
||||
return writer.WriteValueAsync((char)value, cancellationToken);
|
||||
case PrimitiveTypeCode.CharNullable:
|
||||
return writer.WriteValueAsync(value == null ? (char?)null : (char)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Boolean:
|
||||
return writer.WriteValueAsync((bool)value, cancellationToken);
|
||||
case PrimitiveTypeCode.BooleanNullable:
|
||||
return writer.WriteValueAsync(value == null ? (bool?)null : (bool)value, cancellationToken);
|
||||
case PrimitiveTypeCode.SByte:
|
||||
return writer.WriteValueAsync((sbyte)value, cancellationToken);
|
||||
case PrimitiveTypeCode.SByteNullable:
|
||||
return writer.WriteValueAsync(value == null ? (sbyte?)null : (sbyte)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Int16:
|
||||
return writer.WriteValueAsync((short)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Int16Nullable:
|
||||
return writer.WriteValueAsync(value == null ? (short?)null : (short)value, cancellationToken);
|
||||
case PrimitiveTypeCode.UInt16:
|
||||
return writer.WriteValueAsync((ushort)value, cancellationToken);
|
||||
case PrimitiveTypeCode.UInt16Nullable:
|
||||
return writer.WriteValueAsync(value == null ? (ushort?)null : (ushort)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Int32:
|
||||
return writer.WriteValueAsync((int)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Int32Nullable:
|
||||
return writer.WriteValueAsync(value == null ? (int?)null : (int)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Byte:
|
||||
return writer.WriteValueAsync((byte)value, cancellationToken);
|
||||
case PrimitiveTypeCode.ByteNullable:
|
||||
return writer.WriteValueAsync(value == null ? (byte?)null : (byte)value, cancellationToken);
|
||||
case PrimitiveTypeCode.UInt32:
|
||||
return writer.WriteValueAsync((uint)value, cancellationToken);
|
||||
case PrimitiveTypeCode.UInt32Nullable:
|
||||
return writer.WriteValueAsync(value == null ? (uint?)null : (uint)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Int64:
|
||||
return writer.WriteValueAsync((long)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Int64Nullable:
|
||||
return writer.WriteValueAsync(value == null ? (long?)null : (long)value, cancellationToken);
|
||||
case PrimitiveTypeCode.UInt64:
|
||||
return writer.WriteValueAsync((ulong)value, cancellationToken);
|
||||
case PrimitiveTypeCode.UInt64Nullable:
|
||||
return writer.WriteValueAsync(value == null ? (ulong?)null : (ulong)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Single:
|
||||
return writer.WriteValueAsync((float)value, cancellationToken);
|
||||
case PrimitiveTypeCode.SingleNullable:
|
||||
return writer.WriteValueAsync(value == null ? (float?)null : (float)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Double:
|
||||
return writer.WriteValueAsync((double)value, cancellationToken);
|
||||
case PrimitiveTypeCode.DoubleNullable:
|
||||
return writer.WriteValueAsync(value == null ? (double?)null : (double)value, cancellationToken);
|
||||
case PrimitiveTypeCode.DateTime:
|
||||
return writer.WriteValueAsync((DateTime)value, cancellationToken);
|
||||
case PrimitiveTypeCode.DateTimeNullable:
|
||||
return writer.WriteValueAsync(value == null ? (DateTime?)null : (DateTime)value, cancellationToken);
|
||||
case PrimitiveTypeCode.DateTimeOffset:
|
||||
return writer.WriteValueAsync((DateTimeOffset)value, cancellationToken);
|
||||
case PrimitiveTypeCode.DateTimeOffsetNullable:
|
||||
return writer.WriteValueAsync(value == null ? (DateTimeOffset?)null : (DateTimeOffset)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Decimal:
|
||||
return writer.WriteValueAsync((decimal)value, cancellationToken);
|
||||
case PrimitiveTypeCode.DecimalNullable:
|
||||
return writer.WriteValueAsync(value == null ? (decimal?)null : (decimal)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Guid:
|
||||
return writer.WriteValueAsync((Guid)value, cancellationToken);
|
||||
case PrimitiveTypeCode.GuidNullable:
|
||||
return writer.WriteValueAsync(value == null ? (Guid?)null : (Guid)value, cancellationToken);
|
||||
case PrimitiveTypeCode.TimeSpan:
|
||||
return writer.WriteValueAsync((TimeSpan)value, cancellationToken);
|
||||
case PrimitiveTypeCode.TimeSpanNullable:
|
||||
return writer.WriteValueAsync(value == null ? (TimeSpan?)null : (TimeSpan)value, cancellationToken);
|
||||
switch (typeCode)
|
||||
{
|
||||
case PrimitiveTypeCode.Char:
|
||||
return writer.WriteValueAsync((char)value, cancellationToken);
|
||||
case PrimitiveTypeCode.CharNullable:
|
||||
return writer.WriteValueAsync(value == null ? (char?)null : (char)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Boolean:
|
||||
return writer.WriteValueAsync((bool)value, cancellationToken);
|
||||
case PrimitiveTypeCode.BooleanNullable:
|
||||
return writer.WriteValueAsync(value == null ? (bool?)null : (bool)value, cancellationToken);
|
||||
case PrimitiveTypeCode.SByte:
|
||||
return writer.WriteValueAsync((sbyte)value, cancellationToken);
|
||||
case PrimitiveTypeCode.SByteNullable:
|
||||
return writer.WriteValueAsync(value == null ? (sbyte?)null : (sbyte)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Int16:
|
||||
return writer.WriteValueAsync((short)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Int16Nullable:
|
||||
return writer.WriteValueAsync(value == null ? (short?)null : (short)value, cancellationToken);
|
||||
case PrimitiveTypeCode.UInt16:
|
||||
return writer.WriteValueAsync((ushort)value, cancellationToken);
|
||||
case PrimitiveTypeCode.UInt16Nullable:
|
||||
return writer.WriteValueAsync(value == null ? (ushort?)null : (ushort)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Int32:
|
||||
return writer.WriteValueAsync((int)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Int32Nullable:
|
||||
return writer.WriteValueAsync(value == null ? (int?)null : (int)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Byte:
|
||||
return writer.WriteValueAsync((byte)value, cancellationToken);
|
||||
case PrimitiveTypeCode.ByteNullable:
|
||||
return writer.WriteValueAsync(value == null ? (byte?)null : (byte)value, cancellationToken);
|
||||
case PrimitiveTypeCode.UInt32:
|
||||
return writer.WriteValueAsync((uint)value, cancellationToken);
|
||||
case PrimitiveTypeCode.UInt32Nullable:
|
||||
return writer.WriteValueAsync(value == null ? (uint?)null : (uint)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Int64:
|
||||
return writer.WriteValueAsync((long)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Int64Nullable:
|
||||
return writer.WriteValueAsync(value == null ? (long?)null : (long)value, cancellationToken);
|
||||
case PrimitiveTypeCode.UInt64:
|
||||
return writer.WriteValueAsync((ulong)value, cancellationToken);
|
||||
case PrimitiveTypeCode.UInt64Nullable:
|
||||
return writer.WriteValueAsync(value == null ? (ulong?)null : (ulong)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Single:
|
||||
return writer.WriteValueAsync((float)value, cancellationToken);
|
||||
case PrimitiveTypeCode.SingleNullable:
|
||||
return writer.WriteValueAsync(value == null ? (float?)null : (float)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Double:
|
||||
return writer.WriteValueAsync((double)value, cancellationToken);
|
||||
case PrimitiveTypeCode.DoubleNullable:
|
||||
return writer.WriteValueAsync(value == null ? (double?)null : (double)value, cancellationToken);
|
||||
case PrimitiveTypeCode.DateTime:
|
||||
return writer.WriteValueAsync((DateTime)value, cancellationToken);
|
||||
case PrimitiveTypeCode.DateTimeNullable:
|
||||
return writer.WriteValueAsync(value == null ? (DateTime?)null : (DateTime)value, cancellationToken);
|
||||
case PrimitiveTypeCode.DateTimeOffset:
|
||||
return writer.WriteValueAsync((DateTimeOffset)value, cancellationToken);
|
||||
case PrimitiveTypeCode.DateTimeOffsetNullable:
|
||||
return writer.WriteValueAsync(value == null ? (DateTimeOffset?)null : (DateTimeOffset)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Decimal:
|
||||
return writer.WriteValueAsync((decimal)value, cancellationToken);
|
||||
case PrimitiveTypeCode.DecimalNullable:
|
||||
return writer.WriteValueAsync(value == null ? (decimal?)null : (decimal)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Guid:
|
||||
return writer.WriteValueAsync((Guid)value, cancellationToken);
|
||||
case PrimitiveTypeCode.GuidNullable:
|
||||
return writer.WriteValueAsync(value == null ? (Guid?)null : (Guid)value, cancellationToken);
|
||||
case PrimitiveTypeCode.TimeSpan:
|
||||
return writer.WriteValueAsync((TimeSpan)value, cancellationToken);
|
||||
case PrimitiveTypeCode.TimeSpanNullable:
|
||||
return writer.WriteValueAsync(value == null ? (TimeSpan?)null : (TimeSpan)value, cancellationToken);
|
||||
#if HAVE_BIG_INTEGER
|
||||
case PrimitiveTypeCode.BigInteger:
|
||||
case PrimitiveTypeCode.BigInteger:
|
||||
|
||||
// this will call to WriteValueAsync(object)
|
||||
return writer.WriteValueAsync((BigInteger)value, cancellationToken);
|
||||
case PrimitiveTypeCode.BigIntegerNullable:
|
||||
// this will call to WriteValueAsync(object)
|
||||
return writer.WriteValueAsync((BigInteger)value, cancellationToken);
|
||||
case PrimitiveTypeCode.BigIntegerNullable:
|
||||
|
||||
// this will call to WriteValueAsync(object)
|
||||
return writer.WriteValueAsync(value == null ? (BigInteger?)null : (BigInteger)value, cancellationToken);
|
||||
// this will call to WriteValueAsync(object)
|
||||
return writer.WriteValueAsync(value == null ? (BigInteger?)null : (BigInteger)value, cancellationToken);
|
||||
#endif
|
||||
case PrimitiveTypeCode.Uri:
|
||||
return writer.WriteValueAsync((Uri)value, cancellationToken);
|
||||
case PrimitiveTypeCode.String:
|
||||
return writer.WriteValueAsync((string)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Bytes:
|
||||
return writer.WriteValueAsync((byte[])value, cancellationToken);
|
||||
case PrimitiveTypeCode.Uri:
|
||||
return writer.WriteValueAsync((Uri)value, cancellationToken);
|
||||
case PrimitiveTypeCode.String:
|
||||
return writer.WriteValueAsync((string)value, cancellationToken);
|
||||
case PrimitiveTypeCode.Bytes:
|
||||
return writer.WriteValueAsync((byte[])value, cancellationToken);
|
||||
#if HAVE_DB_NULL_TYPE_CODE
|
||||
case PrimitiveTypeCode.DBNull:
|
||||
return writer.WriteNullAsync(cancellationToken);
|
||||
case PrimitiveTypeCode.DBNull:
|
||||
return writer.WriteNullAsync(cancellationToken);
|
||||
#endif
|
||||
default:
|
||||
default:
|
||||
#if HAVE_ICONVERTIBLE
|
||||
if (value is IConvertible convertable)
|
||||
{
|
||||
// the value is a non-standard IConvertible
|
||||
// convert to the underlying value and retry
|
||||
TypeInformation typeInformation = ConvertUtils.GetTypeInformation(convertable);
|
||||
if (value is IConvertible convertible)
|
||||
{
|
||||
// the value is a non-standard IConvertible
|
||||
// convert to the underlying value and retry
|
||||
TypeInformation typeInformation = ConvertUtils.GetTypeInformation(convertible);
|
||||
|
||||
// if convertible has an underlying typecode of Object then attempt to convert it to a string
|
||||
PrimitiveTypeCode resolvedTypeCode = typeInformation.TypeCode == PrimitiveTypeCode.Object ? PrimitiveTypeCode.String : typeInformation.TypeCode;
|
||||
Type resolvedType = typeInformation.TypeCode == PrimitiveTypeCode.Object ? typeof(string) : typeInformation.Type;
|
||||
|
||||
object convertedValue = convertable.ToType(resolvedType, CultureInfo.InvariantCulture);
|
||||
|
||||
return WriteValueAsync(writer, resolvedTypeCode, convertedValue, cancellationToken);
|
||||
}
|
||||
// if convertible has an underlying typecode of Object then attempt to convert it to a string
|
||||
typeCode = typeInformation.TypeCode == PrimitiveTypeCode.Object ? PrimitiveTypeCode.String : typeInformation.TypeCode;
|
||||
Type resolvedType = typeInformation.TypeCode == PrimitiveTypeCode.Object ? typeof(string) : typeInformation.Type;
|
||||
value = convertible.ToType(resolvedType, CultureInfo.InvariantCulture);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
throw CreateUnsupportedTypeException(writer, value);
|
||||
|
||||
// write an unknown null value, fix https://github.com/JamesNK/Newtonsoft.Json/issues/1460
|
||||
if (value == null)
|
||||
{
|
||||
return writer.WriteNullAsync(cancellationToken);
|
||||
}
|
||||
|
||||
throw CreateUnsupportedTypeException(writer, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+186
-149
@@ -1482,163 +1482,200 @@ namespace Newtonsoft.Json
|
||||
|
||||
internal static void WriteValue(JsonWriter writer, PrimitiveTypeCode typeCode, object value)
|
||||
{
|
||||
switch (typeCode)
|
||||
while (true)
|
||||
{
|
||||
case PrimitiveTypeCode.Char:
|
||||
writer.WriteValue((char)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.CharNullable:
|
||||
writer.WriteValue((value == null) ? (char?)null : (char)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Boolean:
|
||||
writer.WriteValue((bool)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.BooleanNullable:
|
||||
writer.WriteValue((value == null) ? (bool?)null : (bool)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.SByte:
|
||||
writer.WriteValue((sbyte)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.SByteNullable:
|
||||
writer.WriteValue((value == null) ? (sbyte?)null : (sbyte)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Int16:
|
||||
writer.WriteValue((short)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Int16Nullable:
|
||||
writer.WriteValue((value == null) ? (short?)null : (short)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.UInt16:
|
||||
writer.WriteValue((ushort)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.UInt16Nullable:
|
||||
writer.WriteValue((value == null) ? (ushort?)null : (ushort)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Int32:
|
||||
writer.WriteValue((int)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Int32Nullable:
|
||||
writer.WriteValue((value == null) ? (int?)null : (int)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Byte:
|
||||
writer.WriteValue((byte)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.ByteNullable:
|
||||
writer.WriteValue((value == null) ? (byte?)null : (byte)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.UInt32:
|
||||
writer.WriteValue((uint)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.UInt32Nullable:
|
||||
writer.WriteValue((value == null) ? (uint?)null : (uint)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Int64:
|
||||
writer.WriteValue((long)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Int64Nullable:
|
||||
writer.WriteValue((value == null) ? (long?)null : (long)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.UInt64:
|
||||
writer.WriteValue((ulong)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.UInt64Nullable:
|
||||
writer.WriteValue((value == null) ? (ulong?)null : (ulong)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Single:
|
||||
writer.WriteValue((float)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.SingleNullable:
|
||||
writer.WriteValue((value == null) ? (float?)null : (float)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Double:
|
||||
writer.WriteValue((double)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.DoubleNullable:
|
||||
writer.WriteValue((value == null) ? (double?)null : (double)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.DateTime:
|
||||
writer.WriteValue((DateTime)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.DateTimeNullable:
|
||||
writer.WriteValue((value == null) ? (DateTime?)null : (DateTime)value);
|
||||
break;
|
||||
switch (typeCode)
|
||||
{
|
||||
case PrimitiveTypeCode.Char:
|
||||
writer.WriteValue((char)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.CharNullable:
|
||||
writer.WriteValue((value == null) ? (char?)null : (char)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.Boolean:
|
||||
writer.WriteValue((bool)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.BooleanNullable:
|
||||
writer.WriteValue((value == null) ? (bool?)null : (bool)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.SByte:
|
||||
writer.WriteValue((sbyte)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.SByteNullable:
|
||||
writer.WriteValue((value == null) ? (sbyte?)null : (sbyte)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.Int16:
|
||||
writer.WriteValue((short)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.Int16Nullable:
|
||||
writer.WriteValue((value == null) ? (short?)null : (short)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.UInt16:
|
||||
writer.WriteValue((ushort)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.UInt16Nullable:
|
||||
writer.WriteValue((value == null) ? (ushort?)null : (ushort)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.Int32:
|
||||
writer.WriteValue((int)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.Int32Nullable:
|
||||
writer.WriteValue((value == null) ? (int?)null : (int)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.Byte:
|
||||
writer.WriteValue((byte)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.ByteNullable:
|
||||
writer.WriteValue((value == null) ? (byte?)null : (byte)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.UInt32:
|
||||
writer.WriteValue((uint)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.UInt32Nullable:
|
||||
writer.WriteValue((value == null) ? (uint?)null : (uint)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.Int64:
|
||||
writer.WriteValue((long)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.Int64Nullable:
|
||||
writer.WriteValue((value == null) ? (long?)null : (long)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.UInt64:
|
||||
writer.WriteValue((ulong)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.UInt64Nullable:
|
||||
writer.WriteValue((value == null) ? (ulong?)null : (ulong)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.Single:
|
||||
writer.WriteValue((float)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.SingleNullable:
|
||||
writer.WriteValue((value == null) ? (float?)null : (float)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.Double:
|
||||
writer.WriteValue((double)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.DoubleNullable:
|
||||
writer.WriteValue((value == null) ? (double?)null : (double)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.DateTime:
|
||||
writer.WriteValue((DateTime)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.DateTimeNullable:
|
||||
writer.WriteValue((value == null) ? (DateTime?)null : (DateTime)value);
|
||||
return;
|
||||
|
||||
#if HAVE_DATE_TIME_OFFSET
|
||||
case PrimitiveTypeCode.DateTimeOffset:
|
||||
writer.WriteValue((DateTimeOffset)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.DateTimeOffsetNullable:
|
||||
writer.WriteValue((value == null) ? (DateTimeOffset?)null : (DateTimeOffset)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.DateTimeOffset:
|
||||
writer.WriteValue((DateTimeOffset)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.DateTimeOffsetNullable:
|
||||
writer.WriteValue((value == null) ? (DateTimeOffset?)null : (DateTimeOffset)value);
|
||||
return;
|
||||
#endif
|
||||
case PrimitiveTypeCode.Decimal:
|
||||
writer.WriteValue((decimal)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.DecimalNullable:
|
||||
writer.WriteValue((value == null) ? (decimal?)null : (decimal)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Guid:
|
||||
writer.WriteValue((Guid)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.GuidNullable:
|
||||
writer.WriteValue((value == null) ? (Guid?)null : (Guid)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.TimeSpan:
|
||||
writer.WriteValue((TimeSpan)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.TimeSpanNullable:
|
||||
writer.WriteValue((value == null) ? (TimeSpan?)null : (TimeSpan)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Decimal:
|
||||
writer.WriteValue((decimal)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.DecimalNullable:
|
||||
writer.WriteValue((value == null) ? (decimal?)null : (decimal)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Guid:
|
||||
writer.WriteValue((Guid)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.GuidNullable:
|
||||
writer.WriteValue((value == null) ? (Guid?)null : (Guid)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.TimeSpan:
|
||||
writer.WriteValue((TimeSpan)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.TimeSpanNullable:
|
||||
writer.WriteValue((value == null) ? (TimeSpan?)null : (TimeSpan)value);
|
||||
return;
|
||||
|
||||
#if HAVE_BIG_INTEGER
|
||||
case PrimitiveTypeCode.BigInteger:
|
||||
// this will call to WriteValue(object)
|
||||
writer.WriteValue((BigInteger)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.BigIntegerNullable:
|
||||
// this will call to WriteValue(object)
|
||||
writer.WriteValue((value == null) ? (BigInteger?)null : (BigInteger)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.BigInteger:
|
||||
// this will call to WriteValue(object)
|
||||
writer.WriteValue((BigInteger)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.BigIntegerNullable:
|
||||
// this will call to WriteValue(object)
|
||||
writer.WriteValue((value == null) ? (BigInteger?)null : (BigInteger)value);
|
||||
return;
|
||||
#endif
|
||||
case PrimitiveTypeCode.Uri:
|
||||
writer.WriteValue((Uri)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.String:
|
||||
writer.WriteValue((string)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Bytes:
|
||||
writer.WriteValue((byte[])value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Uri:
|
||||
writer.WriteValue((Uri)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.String:
|
||||
writer.WriteValue((string)value);
|
||||
return;
|
||||
|
||||
case PrimitiveTypeCode.Bytes:
|
||||
writer.WriteValue((byte[])value);
|
||||
return;
|
||||
|
||||
#if HAVE_DB_NULL_TYPE_CODE
|
||||
case PrimitiveTypeCode.DBNull:
|
||||
writer.WriteNull();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
#if HAVE_ICONVERTIBLE
|
||||
if (value is IConvertible convertible)
|
||||
{
|
||||
// the value is a non-standard IConvertible
|
||||
// convert to the underlying value and retry
|
||||
|
||||
TypeInformation typeInformation = ConvertUtils.GetTypeInformation(convertible);
|
||||
|
||||
// if convertible has an underlying typecode of Object then attempt to convert it to a string
|
||||
PrimitiveTypeCode resolvedTypeCode = (typeInformation.TypeCode == PrimitiveTypeCode.Object) ? PrimitiveTypeCode.String : typeInformation.TypeCode;
|
||||
Type resolvedType = (typeInformation.TypeCode == PrimitiveTypeCode.Object) ? typeof(string) : typeInformation.Type;
|
||||
|
||||
object convertedValue = convertible.ToType(resolvedType, CultureInfo.InvariantCulture);
|
||||
|
||||
WriteValue(writer, resolvedTypeCode, convertedValue);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
// write an unknown null value, fix https://github.com/JamesNK/Newtonsoft.Json/issues/1460
|
||||
if (value == null)
|
||||
{
|
||||
case PrimitiveTypeCode.DBNull:
|
||||
writer.WriteNull();
|
||||
break;
|
||||
}
|
||||
return;
|
||||
#endif
|
||||
default:
|
||||
#if HAVE_ICONVERTIBLE
|
||||
if (value is IConvertible convertible)
|
||||
{
|
||||
// the value is a non-standard IConvertible
|
||||
// convert to the underlying value and retry
|
||||
|
||||
throw CreateUnsupportedTypeException(writer, value);
|
||||
TypeInformation typeInformation = ConvertUtils.GetTypeInformation(convertible);
|
||||
|
||||
// if convertible has an underlying typecode of Object then attempt to convert it to a string
|
||||
typeCode = typeInformation.TypeCode == PrimitiveTypeCode.Object ? PrimitiveTypeCode.String : typeInformation.TypeCode;
|
||||
Type resolvedType = typeInformation.TypeCode == PrimitiveTypeCode.Object ? typeof(string) : typeInformation.Type;
|
||||
value = convertible.ToType(resolvedType, CultureInfo.InvariantCulture);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
// write an unknown null value, fix https://github.com/JamesNK/Newtonsoft.Json/issues/1460
|
||||
if (value == null)
|
||||
{
|
||||
writer.WriteNull();
|
||||
return;
|
||||
}
|
||||
|
||||
throw CreateUnsupportedTypeException(writer, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -353,24 +353,20 @@ namespace Newtonsoft.Json.Utilities
|
||||
|
||||
private static bool InheritsGenericDefinitionInternal(Type currentType, Type genericClassDefinition, out Type implementingType)
|
||||
{
|
||||
if (currentType.IsGenericType())
|
||||
do
|
||||
{
|
||||
Type currentGenericClassDefinition = currentType.GetGenericTypeDefinition();
|
||||
|
||||
if (genericClassDefinition == currentGenericClassDefinition)
|
||||
if (currentType.IsGenericType() && genericClassDefinition == currentType.GetGenericTypeDefinition())
|
||||
{
|
||||
implementingType = currentType;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentType.BaseType() == null)
|
||||
{
|
||||
implementingType = null;
|
||||
return false;
|
||||
currentType = currentType.BaseType();
|
||||
}
|
||||
while (currentType != null);
|
||||
|
||||
return InheritsGenericDefinitionInternal(currentType.BaseType(), genericClassDefinition, out implementingType);
|
||||
implementingType = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user