-Added support for serializing custom IConvertible values
-Refactored away dependency on IConvertible
This commit is contained in:
@@ -63,6 +63,16 @@ namespace Newtonsoft.Json.Tests
|
||||
writer.Close();
|
||||
Assert.IsTrue(ms.CanRead);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteIConvertable()
|
||||
{
|
||||
var sw = new StringWriter();
|
||||
JsonTextWriter writer = new JsonTextWriter(sw);
|
||||
writer.WriteValue(new ConvertibleInt(1));
|
||||
|
||||
Assert.AreEqual("1", sw.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ValueFormatting()
|
||||
@@ -1260,7 +1270,103 @@ _____'propertyName': NaN
|
||||
if (appendDelimiters)
|
||||
writer.Write(delimiter);
|
||||
}
|
||||
}
|
||||
|
||||
public struct ConvertibleInt : IConvertible
|
||||
{
|
||||
private readonly int _value;
|
||||
|
||||
public ConvertibleInt(int value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public TypeCode GetTypeCode()
|
||||
{
|
||||
return TypeCode.Int32;
|
||||
}
|
||||
|
||||
public bool ToBoolean(IFormatProvider provider)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public byte ToByte(IFormatProvider provider)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public char ToChar(IFormatProvider provider)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public DateTime ToDateTime(IFormatProvider provider)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public decimal ToDecimal(IFormatProvider provider)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public double ToDouble(IFormatProvider provider)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public short ToInt16(IFormatProvider provider)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int ToInt32(IFormatProvider provider)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public long ToInt64(IFormatProvider provider)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public sbyte ToSByte(IFormatProvider provider)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public float ToSingle(IFormatProvider provider)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string ToString(IFormatProvider provider)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public object ToType(Type conversionType, IFormatProvider provider)
|
||||
{
|
||||
if (conversionType == typeof(int))
|
||||
return _value;
|
||||
|
||||
throw new Exception("Type not supported: " + conversionType.FullName);
|
||||
}
|
||||
|
||||
public ushort ToUInt16(IFormatProvider provider)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint ToUInt32(IFormatProvider provider)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ulong ToUInt64(IFormatProvider provider)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,7 +100,7 @@ namespace Newtonsoft.Json.Tests
|
||||
DataContractJsonSerializer
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
[Test]
|
||||
public void SerializeSimpleObject()
|
||||
|
||||
@@ -5762,6 +5762,46 @@ To fix this error either change the environment to be fully trusted, change the
|
||||
});
|
||||
}
|
||||
|
||||
public class ConvertableIntTestClass
|
||||
{
|
||||
public ConvertibleInt Integer { get; set; }
|
||||
public ConvertibleInt? NullableInteger1 { get; set; }
|
||||
public ConvertibleInt? NullableInteger2 { get; set; }
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializeIConvertible()
|
||||
{
|
||||
ConvertableIntTestClass c = new ConvertableIntTestClass
|
||||
{
|
||||
Integer = new ConvertibleInt(1),
|
||||
NullableInteger1 = new ConvertibleInt(2),
|
||||
NullableInteger2 = null
|
||||
};
|
||||
|
||||
string json = JsonConvert.SerializeObject(c, Formatting.Indented);
|
||||
|
||||
Assert.AreEqual(@"{
|
||||
""Integer"": 1,
|
||||
""NullableInteger1"": 2,
|
||||
""NullableInteger2"": null
|
||||
}", json);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeserializeIConvertible()
|
||||
{
|
||||
string json = @"{
|
||||
""Integer"": 1,
|
||||
""NullableInteger1"": 2,
|
||||
""NullableInteger2"": null
|
||||
}";
|
||||
|
||||
ExceptionAssert.Throws<JsonSerializationException>(
|
||||
"Error converting value 1 to type 'Newtonsoft.Json.Tests.ConvertibleInt'. Path 'Integer', line 2, position 15.",
|
||||
() => JsonConvert.DeserializeObject<ConvertableIntTestClass>(json));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializeNullableWidgetStruct()
|
||||
{
|
||||
@@ -6352,7 +6392,7 @@ Parameter name: value",
|
||||
[Test]
|
||||
public void DateTimeDictionaryKey_DateTimeOffset_MS()
|
||||
{
|
||||
IDictionary<DateTimeOffset, int> dic1 = new Dictionary<DateTimeOffset, int>
|
||||
IDictionary<DateTimeOffset?, int> dic1 = new Dictionary<DateTimeOffset?, int>
|
||||
{
|
||||
{new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero), 1},
|
||||
{new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero), 2}
|
||||
@@ -6368,7 +6408,7 @@ Parameter name: value",
|
||||
""\/Date(1386850332000+0000)\/"": 2
|
||||
}", json);
|
||||
|
||||
IDictionary<DateTimeOffset, int> dic2 = JsonConvert.DeserializeObject<IDictionary<DateTimeOffset, int>>(json);
|
||||
IDictionary<DateTimeOffset?, int> dic2 = JsonConvert.DeserializeObject<IDictionary<DateTimeOffset?, int>>(json);
|
||||
|
||||
Assert.AreEqual(2, dic2.Count);
|
||||
Assert.AreEqual(1, dic2[new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero)]);
|
||||
|
||||
@@ -70,6 +70,7 @@ namespace Newtonsoft.Json.Converters
|
||||
|
||||
if (char.IsNumber(enumName[0]) || enumName[0] == '-')
|
||||
{
|
||||
// enum value has no name so write number
|
||||
writer.WriteValue(value);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -32,6 +32,7 @@ using System.Numerics;
|
||||
#if !(NET20 || NET35 || SILVERLIGHT)
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json.Converters;
|
||||
@@ -39,9 +40,6 @@ using System.Text;
|
||||
#if !NET20 && (!SILVERLIGHT || WINDOWS_PHONE)
|
||||
using System.Xml.Linq;
|
||||
#endif
|
||||
#if NETFX_CORE || PORTABLE
|
||||
using IConvertible = Newtonsoft.Json.Utilities.Convertible;
|
||||
#endif
|
||||
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
@@ -625,127 +623,77 @@ namespace Newtonsoft.Json
|
||||
if (value == null)
|
||||
return Null;
|
||||
|
||||
IConvertible convertible = ConvertUtils.ToConvertible(value);
|
||||
PrimitiveTypeCode typeCode = ConvertUtils.GetTypeCode(value);
|
||||
|
||||
if (convertible != null)
|
||||
switch (typeCode)
|
||||
{
|
||||
switch (convertible.GetTypeCode())
|
||||
{
|
||||
case TypeCode.String:
|
||||
return ToString(convertible.ToString(CultureInfo.InvariantCulture));
|
||||
case TypeCode.Char:
|
||||
return ToString(convertible.ToChar(CultureInfo.InvariantCulture));
|
||||
case TypeCode.Boolean:
|
||||
return ToString(convertible.ToBoolean(CultureInfo.InvariantCulture));
|
||||
case TypeCode.SByte:
|
||||
return ToString(convertible.ToSByte(CultureInfo.InvariantCulture));
|
||||
case TypeCode.Int16:
|
||||
return ToString(convertible.ToInt16(CultureInfo.InvariantCulture));
|
||||
case TypeCode.UInt16:
|
||||
return ToString(convertible.ToUInt16(CultureInfo.InvariantCulture));
|
||||
case TypeCode.Int32:
|
||||
return ToString(convertible.ToInt32(CultureInfo.InvariantCulture));
|
||||
case TypeCode.Byte:
|
||||
return ToString(convertible.ToByte(CultureInfo.InvariantCulture));
|
||||
case TypeCode.UInt32:
|
||||
return ToString(convertible.ToUInt32(CultureInfo.InvariantCulture));
|
||||
case TypeCode.Int64:
|
||||
return ToString(convertible.ToInt64(CultureInfo.InvariantCulture));
|
||||
case TypeCode.UInt64:
|
||||
return ToString(convertible.ToUInt64(CultureInfo.InvariantCulture));
|
||||
case TypeCode.Single:
|
||||
return ToString(convertible.ToSingle(CultureInfo.InvariantCulture));
|
||||
case TypeCode.Double:
|
||||
return ToString(convertible.ToDouble(CultureInfo.InvariantCulture));
|
||||
case TypeCode.DateTime:
|
||||
return ToString(convertible.ToDateTime(CultureInfo.InvariantCulture));
|
||||
case TypeCode.Decimal:
|
||||
return ToString(convertible.ToDecimal(CultureInfo.InvariantCulture));
|
||||
case PrimitiveTypeCode.String:
|
||||
return ToString((string) value);
|
||||
case PrimitiveTypeCode.Char:
|
||||
return ToString((char) value);
|
||||
case PrimitiveTypeCode.Boolean:
|
||||
return ToString((bool) value);
|
||||
case PrimitiveTypeCode.SByte:
|
||||
return ToString((sbyte) value);
|
||||
case PrimitiveTypeCode.Int16:
|
||||
return ToString((short) value);
|
||||
case PrimitiveTypeCode.UInt16:
|
||||
return ToString((ushort) value);
|
||||
case PrimitiveTypeCode.Int32:
|
||||
return ToString((int) value);
|
||||
case PrimitiveTypeCode.Byte:
|
||||
return ToString((byte) value);
|
||||
case PrimitiveTypeCode.UInt32:
|
||||
return ToString((uint) value);
|
||||
case PrimitiveTypeCode.Int64:
|
||||
return ToString((long) value);
|
||||
case PrimitiveTypeCode.UInt64:
|
||||
return ToString((ulong) value);
|
||||
case PrimitiveTypeCode.Single:
|
||||
return ToString((float) value);
|
||||
case PrimitiveTypeCode.Double:
|
||||
return ToString((double) value);
|
||||
case PrimitiveTypeCode.DateTime:
|
||||
return ToString((DateTime) value);
|
||||
case PrimitiveTypeCode.Decimal:
|
||||
return ToString((decimal) value);
|
||||
#if !(NETFX_CORE || PORTABLE)
|
||||
case TypeCode.DBNull:
|
||||
return Null;
|
||||
case PrimitiveTypeCode.DBNull:
|
||||
return Null;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if !NET20
|
||||
else if (value is DateTimeOffset)
|
||||
{
|
||||
return ToString((DateTimeOffset) value);
|
||||
}
|
||||
case PrimitiveTypeCode.DateTimeOffset:
|
||||
return ToString((DateTimeOffset) value);
|
||||
#endif
|
||||
else if (value is Guid)
|
||||
{
|
||||
return ToString((Guid) value);
|
||||
}
|
||||
else if (value is Uri)
|
||||
{
|
||||
return ToString((Uri) value);
|
||||
}
|
||||
else if (value is TimeSpan)
|
||||
{
|
||||
return ToString((TimeSpan) value);
|
||||
}
|
||||
case PrimitiveTypeCode.Guid:
|
||||
return ToString((Guid) value);
|
||||
case PrimitiveTypeCode.Uri:
|
||||
return ToString((Uri) value);
|
||||
case PrimitiveTypeCode.TimeSpan:
|
||||
return ToString((TimeSpan) value);
|
||||
#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE)
|
||||
else if (value is BigInteger)
|
||||
{
|
||||
return ToString((BigInteger) value);
|
||||
}
|
||||
case PrimitiveTypeCode.BigInteger:
|
||||
return ToString((BigInteger) value);
|
||||
#endif
|
||||
}
|
||||
|
||||
throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
|
||||
}
|
||||
|
||||
private static bool IsJsonPrimitiveTypeCode(TypeCode typeCode)
|
||||
internal static bool IsJsonPrimitiveType(Type t)
|
||||
{
|
||||
switch (typeCode)
|
||||
PrimitiveTypeCode typeCode = ConvertUtils.GetTypeCode(t);
|
||||
|
||||
if (typeCode != PrimitiveTypeCode.Empty && typeCode != PrimitiveTypeCode.Object)
|
||||
return true;
|
||||
|
||||
if (typeof(IConvertible).IsAssignableFrom(t)
|
||||
|| (ReflectionUtils.IsNullableType(t) && typeof(IConvertible).IsAssignableFrom(Nullable.GetUnderlyingType(t))))
|
||||
{
|
||||
case TypeCode.String:
|
||||
case TypeCode.Char:
|
||||
case TypeCode.Boolean:
|
||||
case TypeCode.SByte:
|
||||
case TypeCode.Int16:
|
||||
case TypeCode.UInt16:
|
||||
case TypeCode.Int32:
|
||||
case TypeCode.Byte:
|
||||
case TypeCode.UInt32:
|
||||
case TypeCode.Int64:
|
||||
case TypeCode.UInt64:
|
||||
case TypeCode.Single:
|
||||
case TypeCode.Double:
|
||||
case TypeCode.DateTime:
|
||||
case TypeCode.Decimal:
|
||||
#if !(NETFX_CORE || PORTABLE)
|
||||
case TypeCode.DBNull:
|
||||
#endif
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
return !typeof(JToken).IsAssignableFrom(t);
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool IsJsonPrimitiveType(Type type)
|
||||
{
|
||||
if (ReflectionUtils.IsNullableType(type))
|
||||
type = Nullable.GetUnderlyingType(type);
|
||||
|
||||
#if !NET20
|
||||
if (type == typeof (DateTimeOffset))
|
||||
return true;
|
||||
#endif
|
||||
if (type == typeof (byte[]))
|
||||
return true;
|
||||
if (type == typeof (Uri))
|
||||
return true;
|
||||
if (type == typeof (TimeSpan))
|
||||
return true;
|
||||
if (type == typeof (Guid))
|
||||
return true;
|
||||
#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE)
|
||||
if (type == typeof (BigInteger))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return IsJsonPrimitiveTypeCode(ConvertUtils.GetTypeCode(type));
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static bool TryParseDateTime(string s, DateParseHandling dateParseHandling, DateTimeZoneHandling dateTimeZoneHandling, out object dt)
|
||||
|
||||
@@ -621,9 +621,7 @@ namespace Newtonsoft.Json
|
||||
if (Value != null)
|
||||
{
|
||||
string s;
|
||||
if (ConvertUtils.IsConvertible(Value))
|
||||
s = ConvertUtils.ToConvertible(Value).ToString(Culture);
|
||||
else if (Value is IFormattable)
|
||||
if (Value is IFormattable)
|
||||
s = ((IFormattable)Value).ToString(null, Culture);
|
||||
else
|
||||
s = Value.ToString();
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace Newtonsoft.Json
|
||||
private int _indentation;
|
||||
private char _quoteChar;
|
||||
private bool _quoteName;
|
||||
private bool[] _charEscapeFlags;
|
||||
|
||||
private Base64Encoder Base64Encoder
|
||||
{
|
||||
@@ -86,6 +87,7 @@ namespace Newtonsoft.Json
|
||||
throw new ArgumentException(@"Invalid JavaScript string quote character. Valid quote characters are ' and "".");
|
||||
|
||||
_quoteChar = value;
|
||||
UpdateCharEscapeFlags();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +123,8 @@ namespace Newtonsoft.Json
|
||||
_quoteName = true;
|
||||
_indentChar = ' ';
|
||||
_indentation = 2;
|
||||
|
||||
UpdateCharEscapeFlags();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -209,7 +213,7 @@ namespace Newtonsoft.Json
|
||||
{
|
||||
InternalWritePropertyName(name);
|
||||
|
||||
JavaScriptUtils.WriteEscapedJavaScriptString(_writer, name, _quoteChar, _quoteName, GetCharEscapeFlags(), StringEscapeHandling);
|
||||
JavaScriptUtils.WriteEscapedJavaScriptString(_writer, name, _quoteChar, _quoteName, _charEscapeFlags, StringEscapeHandling);
|
||||
|
||||
_writer.Write(':');
|
||||
}
|
||||
@@ -225,7 +229,7 @@ namespace Newtonsoft.Json
|
||||
|
||||
if (escape)
|
||||
{
|
||||
JavaScriptUtils.WriteEscapedJavaScriptString(_writer, name, _quoteChar, _quoteName, GetCharEscapeFlags(), StringEscapeHandling);
|
||||
JavaScriptUtils.WriteEscapedJavaScriptString(_writer, name, _quoteChar, _quoteName, _charEscapeFlags, StringEscapeHandling);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -241,15 +245,19 @@ namespace Newtonsoft.Json
|
||||
_writer.Write(':');
|
||||
}
|
||||
|
||||
private bool[] GetCharEscapeFlags()
|
||||
internal override void OnStringEscapeHandlingChanged()
|
||||
{
|
||||
UpdateCharEscapeFlags();
|
||||
}
|
||||
|
||||
private void UpdateCharEscapeFlags()
|
||||
{
|
||||
if (StringEscapeHandling == StringEscapeHandling.EscapeHtml)
|
||||
return JavaScriptUtils.HtmlCharEscapeFlags;
|
||||
|
||||
if (_quoteChar == '"')
|
||||
return JavaScriptUtils.DoubleQuoteCharEscapeFlags;
|
||||
|
||||
return JavaScriptUtils.SingleQuoteCharEscapeFlags;
|
||||
_charEscapeFlags = JavaScriptUtils.HtmlCharEscapeFlags;
|
||||
else if (_quoteChar == '"')
|
||||
_charEscapeFlags = JavaScriptUtils.DoubleQuoteCharEscapeFlags;
|
||||
else
|
||||
_charEscapeFlags = JavaScriptUtils.SingleQuoteCharEscapeFlags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -335,7 +343,7 @@ namespace Newtonsoft.Json
|
||||
if (value == null)
|
||||
WriteValueInternal(JsonConvert.Null, JsonToken.Null);
|
||||
else
|
||||
JavaScriptUtils.WriteEscapedJavaScriptString(_writer, value, _quoteChar, true, GetCharEscapeFlags(), StringEscapeHandling);
|
||||
JavaScriptUtils.WriteEscapedJavaScriptString(_writer, value, _quoteChar, true, _charEscapeFlags, StringEscapeHandling);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
+163
-171
@@ -31,9 +31,6 @@ using System.Numerics;
|
||||
#endif
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using System.Globalization;
|
||||
#if NETFX_CORE || PORTABLE
|
||||
using IConvertible = Newtonsoft.Json.Utilities.Convertible;
|
||||
#endif
|
||||
#if NET20
|
||||
using Newtonsoft.Json.Utilities.LinqBridge;
|
||||
#else
|
||||
@@ -250,7 +247,16 @@ namespace Newtonsoft.Json
|
||||
public StringEscapeHandling StringEscapeHandling
|
||||
{
|
||||
get { return _stringEscapeHandling; }
|
||||
set { _stringEscapeHandling = value; }
|
||||
set
|
||||
{
|
||||
_stringEscapeHandling = value;
|
||||
OnStringEscapeHandlingChanged();
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual void OnStringEscapeHandlingChanged()
|
||||
{
|
||||
// hacky but there is a calculated value that relies on StringEscapeHandling
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1254,176 +1260,11 @@ namespace Newtonsoft.Json
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Object"/> value to write.</param>
|
||||
public virtual void WriteValue(object value)
|
||||
{
|
||||
WriteValueInternal(value, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Object"/> value.
|
||||
/// An error will raised if the value cannot be written as a single JSON token.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Object"/> value to write.</param>
|
||||
/// <param name="nullable">A flag indicating whether the value is nullable.</param>
|
||||
public virtual void WriteValue(object value, bool nullable)
|
||||
{
|
||||
WriteValueInternal(value, nullable);
|
||||
}
|
||||
|
||||
private void WriteValueInternal(object value, bool nullable)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
WriteNull();
|
||||
return;
|
||||
}
|
||||
|
||||
IConvertible convertible = ConvertUtils.ToConvertible(value);
|
||||
if (convertible != null)
|
||||
{
|
||||
switch (convertible.GetTypeCode())
|
||||
{
|
||||
case TypeCode.String:
|
||||
WriteValue(convertible.ToString(CultureInfo.InvariantCulture));
|
||||
return;
|
||||
case TypeCode.Char:
|
||||
if (nullable)
|
||||
WriteValue((char?)convertible.ToChar(CultureInfo.InvariantCulture));
|
||||
else
|
||||
WriteValue(convertible.ToChar(CultureInfo.InvariantCulture));
|
||||
return;
|
||||
case TypeCode.Boolean:
|
||||
if (nullable)
|
||||
WriteValue((bool?)convertible.ToBoolean(CultureInfo.InvariantCulture));
|
||||
else
|
||||
WriteValue(convertible.ToBoolean(CultureInfo.InvariantCulture));
|
||||
return;
|
||||
case TypeCode.SByte:
|
||||
if (nullable)
|
||||
WriteValue((sbyte?)convertible.ToSByte(CultureInfo.InvariantCulture));
|
||||
else
|
||||
WriteValue(convertible.ToSByte(CultureInfo.InvariantCulture));
|
||||
return;
|
||||
case TypeCode.Int16:
|
||||
if (nullable)
|
||||
WriteValue((short?)convertible.ToInt16(CultureInfo.InvariantCulture));
|
||||
else
|
||||
WriteValue(convertible.ToInt16(CultureInfo.InvariantCulture));
|
||||
return;
|
||||
case TypeCode.UInt16:
|
||||
if (nullable)
|
||||
WriteValue((ushort?)convertible.ToUInt16(CultureInfo.InvariantCulture));
|
||||
else
|
||||
WriteValue(convertible.ToUInt16(CultureInfo.InvariantCulture));
|
||||
return;
|
||||
case TypeCode.Int32:
|
||||
if (nullable)
|
||||
WriteValue((int?)convertible.ToInt32(CultureInfo.InvariantCulture));
|
||||
else
|
||||
WriteValue(convertible.ToInt32(CultureInfo.InvariantCulture));
|
||||
return;
|
||||
case TypeCode.Byte:
|
||||
if (nullable)
|
||||
WriteValue((byte?)convertible.ToByte(CultureInfo.InvariantCulture));
|
||||
else
|
||||
WriteValue(convertible.ToByte(CultureInfo.InvariantCulture));
|
||||
return;
|
||||
case TypeCode.UInt32:
|
||||
if (nullable)
|
||||
WriteValue((uint?)convertible.ToUInt32(CultureInfo.InvariantCulture));
|
||||
else
|
||||
WriteValue(convertible.ToUInt32(CultureInfo.InvariantCulture));
|
||||
return;
|
||||
case TypeCode.Int64:
|
||||
if (nullable)
|
||||
WriteValue((long?)convertible.ToInt64(CultureInfo.InvariantCulture));
|
||||
else
|
||||
WriteValue(convertible.ToInt64(CultureInfo.InvariantCulture));
|
||||
return;
|
||||
case TypeCode.UInt64:
|
||||
if (nullable)
|
||||
WriteValue((ulong?)convertible.ToUInt64(CultureInfo.InvariantCulture));
|
||||
else
|
||||
WriteValue(convertible.ToUInt64(CultureInfo.InvariantCulture));
|
||||
return;
|
||||
case TypeCode.Single:
|
||||
if (nullable)
|
||||
WriteValue((float?)convertible.ToSingle(CultureInfo.InvariantCulture));
|
||||
else
|
||||
WriteValue(convertible.ToSingle(CultureInfo.InvariantCulture));
|
||||
return;
|
||||
case TypeCode.Double:
|
||||
if (nullable)
|
||||
WriteValue((double?)convertible.ToDouble(CultureInfo.InvariantCulture));
|
||||
else
|
||||
WriteValue(convertible.ToDouble(CultureInfo.InvariantCulture));
|
||||
return;
|
||||
case TypeCode.DateTime:
|
||||
if (nullable)
|
||||
WriteValue((DateTime?)convertible.ToDateTime(CultureInfo.InvariantCulture));
|
||||
else
|
||||
WriteValue(convertible.ToDateTime(CultureInfo.InvariantCulture));
|
||||
return;
|
||||
case TypeCode.Decimal:
|
||||
if (nullable)
|
||||
WriteValue((decimal?)convertible.ToDecimal(CultureInfo.InvariantCulture));
|
||||
else
|
||||
WriteValue(convertible.ToDecimal(CultureInfo.InvariantCulture));
|
||||
return;
|
||||
#if !(NETFX_CORE || PORTABLE)
|
||||
case TypeCode.DBNull:
|
||||
WriteNull();
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if !NET20
|
||||
else if (value is DateTimeOffset)
|
||||
{
|
||||
if (nullable)
|
||||
WriteValue((DateTimeOffset?)value);
|
||||
else
|
||||
WriteValue((DateTimeOffset)value);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
else if (value is byte[])
|
||||
{
|
||||
WriteValue((byte[])value);
|
||||
return;
|
||||
}
|
||||
else if (value is Guid)
|
||||
{
|
||||
if (nullable)
|
||||
WriteValue((Guid?)value);
|
||||
else
|
||||
WriteValue((Guid)value);
|
||||
return;
|
||||
}
|
||||
else if (value is Uri)
|
||||
{
|
||||
WriteValue((Uri)value);
|
||||
return;
|
||||
}
|
||||
else if (value is TimeSpan)
|
||||
{
|
||||
if (nullable)
|
||||
WriteValue((TimeSpan?)value);
|
||||
else
|
||||
WriteValue((TimeSpan)value);
|
||||
return;
|
||||
}
|
||||
#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE)
|
||||
else if (value is BigInteger)
|
||||
{
|
||||
if (nullable)
|
||||
WriteValue((BigInteger?)value);
|
||||
else
|
||||
WriteValue((BigInteger)value);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
throw JsonWriterException.Create(this, "Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null);
|
||||
else
|
||||
WriteValue(this, ConvertUtils.GetTypeCode(value), value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -1469,5 +1310,156 @@ namespace Newtonsoft.Json
|
||||
if (_currentState != State.Closed)
|
||||
Close();
|
||||
}
|
||||
|
||||
internal static void WriteValue(JsonWriter writer, PrimitiveTypeCode typeCode, object value)
|
||||
{
|
||||
switch (typeCode)
|
||||
{
|
||||
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;
|
||||
#if !NET20
|
||||
case PrimitiveTypeCode.DateTimeOffset:
|
||||
writer.WriteValue((DateTimeOffset)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.DateTimeOffsetNullable:
|
||||
writer.WriteValue((value == null) ? (DateTimeOffset?)null : (DateTimeOffset)value);
|
||||
break;
|
||||
#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;
|
||||
#if !(PORTABLE || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT)
|
||||
case PrimitiveTypeCode.BigInteger:
|
||||
writer.WriteValue((BigInteger)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.BigIntegerNullable:
|
||||
writer.WriteValue((value == null) ? (BigInteger?)null : (BigInteger)value);
|
||||
break;
|
||||
#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;
|
||||
#if !(PORTABLE || NETFX_CORE)
|
||||
case PrimitiveTypeCode.DBNull:
|
||||
writer.WriteNull();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
#if !(PORTABLE || NETFX_CORE)
|
||||
if (value is IConvertible)
|
||||
{
|
||||
// the value is a non-standard IConvertible
|
||||
// convert to the underlying value and retry
|
||||
IConvertible convertable = (IConvertible)value;
|
||||
TypeInformation typeInformation = ConvertUtils.GetTypeInformation(convertable);
|
||||
object convertedValue = convertable.ToType(typeInformation.Type, CultureInfo.InvariantCulture);
|
||||
|
||||
WriteValue(writer, typeInformation.TypeCode, convertedValue);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
throw JsonWriterException.Create(writer, "Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1636,126 +1636,91 @@ namespace Newtonsoft.Json.Linq
|
||||
|
||||
private object ToObject(Type objectType, bool isNullable)
|
||||
{
|
||||
TypeCode typeCode = ConvertUtils.GetTypeCode(objectType);
|
||||
PrimitiveTypeCode typeCode = ConvertUtils.GetTypeCode(objectType);
|
||||
|
||||
switch (typeCode)
|
||||
{
|
||||
case TypeCode.Object:
|
||||
if (!isNullable && ReflectionUtils.IsNullableType(objectType))
|
||||
return ToObject(Nullable.GetUnderlyingType(objectType), true);
|
||||
|
||||
// fall back to standard JsonSerializer
|
||||
break;
|
||||
case TypeCode.Boolean:
|
||||
if (isNullable)
|
||||
return (bool?) this;
|
||||
|
||||
case PrimitiveTypeCode.BooleanNullable:
|
||||
return (bool?) this;
|
||||
case PrimitiveTypeCode.Boolean:
|
||||
return (bool) this;
|
||||
case TypeCode.Char:
|
||||
if (isNullable)
|
||||
return (char?) this;
|
||||
|
||||
case PrimitiveTypeCode.CharNullable:
|
||||
return (char?) this;
|
||||
case PrimitiveTypeCode.Char:
|
||||
return (char) this;
|
||||
case TypeCode.SByte:
|
||||
if (isNullable)
|
||||
return (sbyte?) this;
|
||||
|
||||
case PrimitiveTypeCode.SByte:
|
||||
return (sbyte?) this;
|
||||
case PrimitiveTypeCode.SByteNullable:
|
||||
return (sbyte) this;
|
||||
case TypeCode.Byte:
|
||||
if (isNullable)
|
||||
return (byte?) this;
|
||||
|
||||
case PrimitiveTypeCode.ByteNullable:
|
||||
return (byte?) this;
|
||||
case PrimitiveTypeCode.Byte:
|
||||
return (byte) this;
|
||||
case TypeCode.Int16:
|
||||
if (isNullable)
|
||||
return (short?) this;
|
||||
|
||||
case PrimitiveTypeCode.Int16Nullable:
|
||||
return (short?) this;
|
||||
case PrimitiveTypeCode.Int16:
|
||||
return (short) this;
|
||||
case TypeCode.UInt16:
|
||||
if (isNullable)
|
||||
return (ushort?) this;
|
||||
|
||||
case PrimitiveTypeCode.UInt16Nullable:
|
||||
return (ushort?) this;
|
||||
case PrimitiveTypeCode.UInt16:
|
||||
return (ushort) this;
|
||||
case TypeCode.Int32:
|
||||
if (isNullable)
|
||||
return (int?) this;
|
||||
|
||||
case PrimitiveTypeCode.Int32Nullable:
|
||||
return (int?) this;
|
||||
case PrimitiveTypeCode.Int32:
|
||||
return (int) this;
|
||||
case TypeCode.UInt32:
|
||||
if (isNullable)
|
||||
return (uint?) this;
|
||||
|
||||
case PrimitiveTypeCode.UInt32Nullable:
|
||||
return (uint?) this;
|
||||
case PrimitiveTypeCode.UInt32:
|
||||
return (uint) this;
|
||||
case TypeCode.Int64:
|
||||
if (isNullable)
|
||||
return (long?) this;
|
||||
|
||||
case PrimitiveTypeCode.Int64Nullable:
|
||||
return (long?) this;
|
||||
case PrimitiveTypeCode.Int64:
|
||||
return (long) this;
|
||||
case TypeCode.UInt64:
|
||||
if (isNullable)
|
||||
return (ulong?) this;
|
||||
|
||||
case PrimitiveTypeCode.UInt64Nullable:
|
||||
return (ulong?) this;
|
||||
case PrimitiveTypeCode.UInt64:
|
||||
return (ulong) this;
|
||||
case TypeCode.Single:
|
||||
if (isNullable)
|
||||
return (float?) this;
|
||||
|
||||
case PrimitiveTypeCode.SingleNullable:
|
||||
return (float?) this;
|
||||
case PrimitiveTypeCode.Single:
|
||||
return (float) this;
|
||||
case TypeCode.Double:
|
||||
if (isNullable)
|
||||
return (double?) this;
|
||||
|
||||
case PrimitiveTypeCode.DoubleNullable:
|
||||
return (double?) this;
|
||||
case PrimitiveTypeCode.Double:
|
||||
return (double) this;
|
||||
case TypeCode.Decimal:
|
||||
if (isNullable)
|
||||
return (decimal?) this;
|
||||
|
||||
case PrimitiveTypeCode.DecimalNullable:
|
||||
return (decimal?) this;
|
||||
case PrimitiveTypeCode.Decimal:
|
||||
return (decimal) this;
|
||||
case TypeCode.DateTime:
|
||||
if (isNullable)
|
||||
return (DateTime?) this;
|
||||
|
||||
case PrimitiveTypeCode.DateTimeNullable:
|
||||
return (DateTime?) this;
|
||||
case PrimitiveTypeCode.DateTime:
|
||||
return (DateTime) this;
|
||||
case TypeCode.String:
|
||||
return (string) this;
|
||||
}
|
||||
|
||||
#if !NET20
|
||||
if (objectType == typeof (DateTimeOffset))
|
||||
{
|
||||
if (isNullable)
|
||||
case PrimitiveTypeCode.DateTimeOffsetNullable:
|
||||
return (DateTimeOffset?) this;
|
||||
|
||||
return (DateTimeOffset) this;
|
||||
}
|
||||
case PrimitiveTypeCode.DateTimeOffset:
|
||||
return (DateTimeOffset) this;
|
||||
#endif
|
||||
if (objectType == typeof (Guid))
|
||||
{
|
||||
if (isNullable)
|
||||
case PrimitiveTypeCode.String:
|
||||
return (string) this;
|
||||
case PrimitiveTypeCode.GuidNullable:
|
||||
return (Guid?) this;
|
||||
|
||||
return (Guid) this;
|
||||
}
|
||||
if (objectType == typeof (Uri))
|
||||
{
|
||||
return (Uri) this;
|
||||
}
|
||||
if (objectType == typeof (TimeSpan))
|
||||
{
|
||||
if (isNullable)
|
||||
return (TimeSpan?) this;
|
||||
|
||||
return (TimeSpan) this;
|
||||
}
|
||||
case PrimitiveTypeCode.Guid:
|
||||
return (Guid) this;
|
||||
case PrimitiveTypeCode.Uri:
|
||||
return (Uri) this;
|
||||
case PrimitiveTypeCode.TimeSpanNullable:
|
||||
return (TimeSpan?)this;
|
||||
case PrimitiveTypeCode.TimeSpan:
|
||||
return (TimeSpan)this;
|
||||
#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE)
|
||||
if (objectType == typeof(BigInteger))
|
||||
{
|
||||
if (isNullable)
|
||||
case PrimitiveTypeCode.BigIntegerNullable:
|
||||
return (BigInteger?)this;
|
||||
|
||||
return (BigInteger)this;
|
||||
}
|
||||
case PrimitiveTypeCode.BigInteger:
|
||||
return (BigInteger)this;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ToObject(objectType, new JsonSerializer());
|
||||
}
|
||||
|
||||
@@ -30,9 +30,6 @@ using System.Collections.Generic;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
#if NETFX_CORE
|
||||
using IConvertible = Newtonsoft.Json.Utilities.Convertible;
|
||||
#endif
|
||||
#if NET20
|
||||
using Newtonsoft.Json.Utilities.LinqBridge;
|
||||
#else
|
||||
@@ -321,8 +318,10 @@ namespace Newtonsoft.Json.Schema
|
||||
|
||||
if (keyType != null)
|
||||
{
|
||||
JsonContract keyContract = ContractResolver.ResolveContract(keyType);
|
||||
|
||||
// can be converted to a string
|
||||
if (ConvertUtils.IsConvertible(keyType))
|
||||
if (keyContract.ContractType == JsonContractType.Primitive)
|
||||
{
|
||||
CurrentSchema.AdditionalProperties = GenerateInternal(valueType, Required.Default, false);
|
||||
}
|
||||
@@ -421,38 +420,44 @@ namespace Newtonsoft.Json.Schema
|
||||
type = Nullable.GetUnderlyingType(type);
|
||||
}
|
||||
|
||||
TypeCode typeCode = ConvertUtils.GetTypeCode(type);
|
||||
PrimitiveTypeCode typeCode = ConvertUtils.GetTypeCode(type);
|
||||
|
||||
switch (typeCode)
|
||||
{
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.Object:
|
||||
case PrimitiveTypeCode.Empty:
|
||||
case PrimitiveTypeCode.Object:
|
||||
return schemaType | JsonSchemaType.String;
|
||||
#if !(NETFX_CORE || PORTABLE)
|
||||
case TypeCode.DBNull:
|
||||
case PrimitiveTypeCode.DBNull:
|
||||
return schemaType | JsonSchemaType.Null;
|
||||
#endif
|
||||
case TypeCode.Boolean:
|
||||
case PrimitiveTypeCode.Boolean:
|
||||
return schemaType | JsonSchemaType.Boolean;
|
||||
case TypeCode.Char:
|
||||
case PrimitiveTypeCode.Char:
|
||||
return schemaType | JsonSchemaType.String;
|
||||
case TypeCode.SByte:
|
||||
case TypeCode.Byte:
|
||||
case TypeCode.Int16:
|
||||
case TypeCode.UInt16:
|
||||
case TypeCode.Int32:
|
||||
case TypeCode.UInt32:
|
||||
case TypeCode.Int64:
|
||||
case TypeCode.UInt64:
|
||||
case PrimitiveTypeCode.SByte:
|
||||
case PrimitiveTypeCode.Byte:
|
||||
case PrimitiveTypeCode.Int16:
|
||||
case PrimitiveTypeCode.UInt16:
|
||||
case PrimitiveTypeCode.Int32:
|
||||
case PrimitiveTypeCode.UInt32:
|
||||
case PrimitiveTypeCode.Int64:
|
||||
case PrimitiveTypeCode.UInt64:
|
||||
case PrimitiveTypeCode.BigInteger:
|
||||
return schemaType | JsonSchemaType.Integer;
|
||||
case TypeCode.Single:
|
||||
case TypeCode.Double:
|
||||
case TypeCode.Decimal:
|
||||
case PrimitiveTypeCode.Single:
|
||||
case PrimitiveTypeCode.Double:
|
||||
case PrimitiveTypeCode.Decimal:
|
||||
return schemaType | JsonSchemaType.Float;
|
||||
// convert to string?
|
||||
case TypeCode.DateTime:
|
||||
case PrimitiveTypeCode.DateTime:
|
||||
case PrimitiveTypeCode.DateTimeOffset:
|
||||
return schemaType | JsonSchemaType.String;
|
||||
case TypeCode.String:
|
||||
case PrimitiveTypeCode.String:
|
||||
case PrimitiveTypeCode.Uri:
|
||||
case PrimitiveTypeCode.Guid:
|
||||
case PrimitiveTypeCode.TimeSpan:
|
||||
case PrimitiveTypeCode.Bytes:
|
||||
return schemaType | JsonSchemaType.String;
|
||||
default:
|
||||
throw new JsonException("Unexpected type code '{0}' for type '{1}'.".FormatWith(CultureInfo.InvariantCulture, typeCode, type));
|
||||
|
||||
@@ -781,7 +781,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
{
|
||||
Type t = ReflectionUtils.EnsureNotNullableType(objectType);
|
||||
|
||||
if (JsonConvert.IsJsonPrimitiveType(t))
|
||||
if (JsonConvert.IsJsonPrimitiveType(objectType))
|
||||
return CreatePrimitiveContract(objectType);
|
||||
|
||||
if (JsonTypeReflector.GetJsonObjectAttribute(t) != null)
|
||||
|
||||
@@ -28,9 +28,6 @@ using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
#if NETFX_CORE
|
||||
using IConvertible = Newtonsoft.Json.Utilities.Convertible;
|
||||
#endif
|
||||
|
||||
namespace Newtonsoft.Json.Serialization
|
||||
{
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
#if !(PORTABLE || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT)
|
||||
using System.Globalization;
|
||||
using System.Numerics;
|
||||
#endif
|
||||
using Newtonsoft.Json.Utilities;
|
||||
@@ -37,57 +37,6 @@ namespace Newtonsoft.Json.Serialization
|
||||
/// </summary>
|
||||
public class JsonPrimitiveContract : JsonContract
|
||||
{
|
||||
private static readonly Dictionary<Type, PrimitiveTypeCode> TypeCodeMap =
|
||||
new Dictionary<Type, PrimitiveTypeCode>
|
||||
{
|
||||
{ typeof(char), PrimitiveTypeCode.Char },
|
||||
{ typeof(char?), PrimitiveTypeCode.CharNullable },
|
||||
{ typeof(bool), PrimitiveTypeCode.Boolean },
|
||||
{ typeof(bool?), PrimitiveTypeCode.BooleanNullable },
|
||||
{ typeof(sbyte), PrimitiveTypeCode.SByte },
|
||||
{ typeof(sbyte?), PrimitiveTypeCode.SByteNullable },
|
||||
{ typeof(short), PrimitiveTypeCode.Int16 },
|
||||
{ typeof(short?), PrimitiveTypeCode.Int16Nullable },
|
||||
{ typeof(ushort), PrimitiveTypeCode.UInt16 },
|
||||
{ typeof(ushort?), PrimitiveTypeCode.UInt16Nullable },
|
||||
{ typeof(int), PrimitiveTypeCode.Int32 },
|
||||
{ typeof(int?), PrimitiveTypeCode.Int32Nullable },
|
||||
{ typeof(byte), PrimitiveTypeCode.Byte },
|
||||
{ typeof(byte?), PrimitiveTypeCode.ByteNullable },
|
||||
{ typeof(uint), PrimitiveTypeCode.UInt32 },
|
||||
{ typeof(uint?), PrimitiveTypeCode.UInt32Nullable },
|
||||
{ typeof(long), PrimitiveTypeCode.Int64 },
|
||||
{ typeof(long?), PrimitiveTypeCode.Int64Nullable },
|
||||
{ typeof(ulong), PrimitiveTypeCode.UInt64 },
|
||||
{ typeof(ulong?), PrimitiveTypeCode.UInt64Nullable },
|
||||
{ typeof(float), PrimitiveTypeCode.Single },
|
||||
{ typeof(float?), PrimitiveTypeCode.SingleNullable },
|
||||
{ typeof(double), PrimitiveTypeCode.Double },
|
||||
{ typeof(double?), PrimitiveTypeCode.DoubleNullable },
|
||||
{ typeof(DateTime), PrimitiveTypeCode.DateTime },
|
||||
{ typeof(DateTime?), PrimitiveTypeCode.DateTimeNullable },
|
||||
#if !NET20
|
||||
{ typeof(DateTimeOffset), PrimitiveTypeCode.DateTimeOffset },
|
||||
{ typeof(DateTimeOffset?), PrimitiveTypeCode.DateTimeOffsetNullable },
|
||||
#endif
|
||||
{ typeof(decimal), PrimitiveTypeCode.Decimal },
|
||||
{ typeof(decimal?), PrimitiveTypeCode.DecimalNullable },
|
||||
{ typeof(Guid), PrimitiveTypeCode.Guid },
|
||||
{ typeof(Guid?), PrimitiveTypeCode.GuidNullable },
|
||||
{ typeof(TimeSpan), PrimitiveTypeCode.TimeSpan },
|
||||
{ typeof(TimeSpan?), PrimitiveTypeCode.TimeSpanNullable },
|
||||
#if !(PORTABLE || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT)
|
||||
{ typeof(BigInteger), PrimitiveTypeCode.BigInteger },
|
||||
{ typeof(BigInteger?), PrimitiveTypeCode.BigIntegerNullable },
|
||||
#endif
|
||||
{ typeof(Uri), PrimitiveTypeCode.Uri },
|
||||
{ typeof(string), PrimitiveTypeCode.String },
|
||||
{ typeof(byte[]), PrimitiveTypeCode.Bytes },
|
||||
#if !(PORTABLE || NETFX_CORE)
|
||||
{ typeof(DBNull), PrimitiveTypeCode.DBNull }
|
||||
#endif
|
||||
};
|
||||
|
||||
internal PrimitiveTypeCode TypeCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -99,256 +48,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
{
|
||||
ContractType = JsonContractType.Primitive;
|
||||
|
||||
// get the underlying enum value
|
||||
Type t;
|
||||
if (ReflectionUtils.IsNullableType(underlyingType))
|
||||
t = Nullable.GetUnderlyingType(underlyingType).IsEnum() ? ReflectionUtils.MakeGenericType(typeof(Nullable<>), Enum.GetUnderlyingType(Nullable.GetUnderlyingType(underlyingType))) : underlyingType;
|
||||
else
|
||||
t = underlyingType.IsEnum() ? Enum.GetUnderlyingType(underlyingType) : underlyingType;
|
||||
|
||||
PrimitiveTypeCode typeCode;
|
||||
TypeCodeMap.TryGetValue(t, out typeCode);
|
||||
TypeCode = typeCode;
|
||||
TypeCode = ConvertUtils.GetTypeCode(underlyingType);
|
||||
}
|
||||
|
||||
internal void WriteValue(JsonWriter writer, object value)
|
||||
{
|
||||
switch (TypeCode)
|
||||
{
|
||||
case PrimitiveTypeCode.Char:
|
||||
writer.WriteValue((char)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.CharNullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((char)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
case PrimitiveTypeCode.Boolean:
|
||||
writer.WriteValue((bool)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.BooleanNullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((bool)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
case PrimitiveTypeCode.SByte:
|
||||
writer.WriteValue((sbyte)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.SByteNullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((sbyte)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
case PrimitiveTypeCode.Int16:
|
||||
writer.WriteValue((short)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Int16Nullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((short)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
case PrimitiveTypeCode.UInt16:
|
||||
writer.WriteValue((ushort)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.UInt16Nullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((ushort)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
case PrimitiveTypeCode.Int32:
|
||||
writer.WriteValue((int)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Int32Nullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((int)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
case PrimitiveTypeCode.Byte:
|
||||
writer.WriteValue((byte)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.ByteNullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((byte)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
case PrimitiveTypeCode.UInt32:
|
||||
writer.WriteValue((uint)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.UInt32Nullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((uint)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
case PrimitiveTypeCode.Int64:
|
||||
writer.WriteValue((long)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.Int64Nullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((long)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
case PrimitiveTypeCode.UInt64:
|
||||
writer.WriteValue((ulong)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.UInt64Nullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((ulong)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
case PrimitiveTypeCode.Single:
|
||||
writer.WriteValue((float)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.SingleNullable:
|
||||
// use nullable WriteValue to handle NaN, Infinity with FloatFormatHandling
|
||||
if (value != null)
|
||||
writer.WriteValue((float?)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
case PrimitiveTypeCode.Double:
|
||||
writer.WriteValue((double)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.DoubleNullable:
|
||||
// use nullable WriteValue to handle NaN, Infinity with FloatFormatHandling
|
||||
if (value != null)
|
||||
writer.WriteValue((double?)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
case PrimitiveTypeCode.DateTime:
|
||||
writer.WriteValue((DateTime)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.DateTimeNullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((DateTime)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
#if !NET20
|
||||
case PrimitiveTypeCode.DateTimeOffset:
|
||||
writer.WriteValue((DateTimeOffset)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.DateTimeOffsetNullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((DateTimeOffset)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
#endif
|
||||
case PrimitiveTypeCode.Decimal:
|
||||
writer.WriteValue((decimal)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.DecimalNullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((decimal)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
case PrimitiveTypeCode.Guid:
|
||||
writer.WriteValue((Guid)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.GuidNullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((Guid)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
case PrimitiveTypeCode.TimeSpan:
|
||||
writer.WriteValue((TimeSpan)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.TimeSpanNullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((TimeSpan)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
#if !(PORTABLE || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT)
|
||||
case PrimitiveTypeCode.BigInteger:
|
||||
writer.WriteValue((BigInteger)value);
|
||||
break;
|
||||
case PrimitiveTypeCode.BigIntegerNullable:
|
||||
if (value != null)
|
||||
writer.WriteValue((BigInteger)value);
|
||||
else
|
||||
writer.WriteNull();
|
||||
break;
|
||||
#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;
|
||||
#if !(PORTABLE || NETFX_CORE)
|
||||
case PrimitiveTypeCode.DBNull:
|
||||
writer.WriteNull();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("Could not write type: " + UnderlyingType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal enum PrimitiveTypeCode
|
||||
{
|
||||
Unknown,
|
||||
Char,
|
||||
CharNullable,
|
||||
Boolean,
|
||||
BooleanNullable,
|
||||
SByte,
|
||||
SByteNullable,
|
||||
Int16,
|
||||
Int16Nullable,
|
||||
UInt16,
|
||||
UInt16Nullable,
|
||||
Int32,
|
||||
Int32Nullable,
|
||||
Byte,
|
||||
ByteNullable,
|
||||
UInt32,
|
||||
UInt32Nullable,
|
||||
Int64,
|
||||
Int64Nullable,
|
||||
UInt64,
|
||||
UInt64Nullable,
|
||||
Single,
|
||||
SingleNullable,
|
||||
Double,
|
||||
DoubleNullable,
|
||||
DateTime,
|
||||
DateTimeNullable,
|
||||
#if !NET20
|
||||
DateTimeOffset,
|
||||
DateTimeOffsetNullable,
|
||||
#endif
|
||||
Decimal,
|
||||
DecimalNullable,
|
||||
Guid,
|
||||
GuidNullable,
|
||||
TimeSpan,
|
||||
TimeSpanNullable,
|
||||
#if !(PORTABLE || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT)
|
||||
BigInteger,
|
||||
BigIntegerNullable,
|
||||
#endif
|
||||
Uri,
|
||||
String,
|
||||
Bytes,
|
||||
DBNull
|
||||
}
|
||||
}
|
||||
@@ -693,11 +693,13 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
|
||||
|
||||
if (contract.IsConvertable)
|
||||
{
|
||||
JsonPrimitiveContract primitiveContract = (JsonPrimitiveContract)contract;
|
||||
|
||||
if (contract.NonNullableUnderlyingType.IsEnum())
|
||||
{
|
||||
if (value is string)
|
||||
return Enum.Parse(contract.NonNullableUnderlyingType, value.ToString(), true);
|
||||
else if (ConvertUtils.IsInteger(value))
|
||||
else if (ConvertUtils.IsInteger(primitiveContract.TypeCode))
|
||||
return Enum.ToObject(contract.NonNullableUnderlyingType, value);
|
||||
}
|
||||
|
||||
@@ -706,6 +708,7 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
|
||||
return ConvertUtils.FromBigInteger((BigInteger)value, targetType);
|
||||
#endif
|
||||
|
||||
// this won't work when converting to a custom IConvertible
|
||||
return Convert.ChangeType(value, contract.NonNullableUnderlyingType, culture);
|
||||
}
|
||||
|
||||
@@ -966,6 +969,7 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
|
||||
contract.ItemContract = GetContractSafe(contract.DictionaryValueType);
|
||||
|
||||
JsonConverter dictionaryValueConverter = contract.ItemConverter ?? GetConverter(contract.ItemContract, null, contract, containerProperty);
|
||||
PrimitiveTypeCode keyTypeCode = (contract.KeyContract is JsonPrimitiveContract) ? ((JsonPrimitiveContract)contract.KeyContract).TypeCode : PrimitiveTypeCode.Empty;
|
||||
|
||||
bool finished = false;
|
||||
do
|
||||
@@ -979,11 +983,13 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
|
||||
try
|
||||
{
|
||||
// this is for correctly reading ISO and MS formatted dictionary keys
|
||||
if (contract.DictionaryKeyType == typeof(DateTime) && JsonConvert.TryParseDateTime(keyValue.ToString(), DateParseHandling.DateTime, reader.DateTimeZoneHandling, out keyValue))
|
||||
if ((keyTypeCode == PrimitiveTypeCode.DateTime || keyTypeCode == PrimitiveTypeCode.DateTimeNullable)
|
||||
&& JsonConvert.TryParseDateTime(keyValue.ToString(), DateParseHandling.DateTime, reader.DateTimeZoneHandling, out keyValue))
|
||||
{
|
||||
}
|
||||
#if !NET20
|
||||
else if (contract.DictionaryKeyType == typeof(DateTimeOffset) && JsonConvert.TryParseDateTime(keyValue.ToString(), DateParseHandling.DateTimeOffset, reader.DateTimeZoneHandling, out keyValue))
|
||||
else if ((keyTypeCode == PrimitiveTypeCode.DateTimeOffset || keyTypeCode == PrimitiveTypeCode.DateTimeOffsetNullable)
|
||||
&& JsonConvert.TryParseDateTime(keyValue.ToString(), DateParseHandling.DateTimeOffset, reader.DateTimeZoneHandling, out keyValue))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -94,14 +94,14 @@ namespace Newtonsoft.Json.Serialization
|
||||
WriteTypeProperty(writer, contract.CreatedType);
|
||||
writer.WritePropertyName(JsonTypeReflector.ValuePropertyName);
|
||||
|
||||
contract.WriteValue(writer, value);
|
||||
JsonWriter.WriteValue(writer, contract.TypeCode, value);
|
||||
|
||||
writer.WriteEndObject();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
contract.WriteValue(writer, value);
|
||||
JsonWriter.WriteValue(writer, contract.TypeCode, value);
|
||||
}
|
||||
|
||||
private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
|
||||
@@ -827,12 +827,15 @@ To fix this error either change the environment to be fully trusted, change the
|
||||
if (contract.ItemContract == null)
|
||||
contract.ItemContract = Serializer.ContractResolver.ResolveContract(contract.DictionaryValueType ?? typeof(object));
|
||||
|
||||
if (contract.KeyContract == null)
|
||||
contract.KeyContract = Serializer.ContractResolver.ResolveContract(contract.DictionaryKeyType ?? typeof(object));
|
||||
|
||||
int initialDepth = writer.Top;
|
||||
|
||||
foreach (DictionaryEntry entry in values)
|
||||
{
|
||||
bool escape;
|
||||
string propertyName = GetPropertyName(writer, entry, out escape);
|
||||
string propertyName = GetPropertyName(writer, entry, contract.KeyContract, out escape);
|
||||
|
||||
propertyName = (contract.PropertyNameResolver != null)
|
||||
? contract.PropertyNameResolver(propertyName)
|
||||
@@ -874,32 +877,36 @@ To fix this error either change the environment to be fully trusted, change the
|
||||
OnSerialized(writer, contract, underlyingDictionary);
|
||||
}
|
||||
|
||||
private string GetPropertyName(JsonWriter writer, DictionaryEntry entry, out bool escape)
|
||||
private string GetPropertyName(JsonWriter writer, DictionaryEntry entry, JsonContract contract, out bool escape)
|
||||
{
|
||||
object key = entry.Key;
|
||||
|
||||
string propertyName;
|
||||
|
||||
if (key is DateTime)
|
||||
JsonPrimitiveContract primitiveContract = contract as JsonPrimitiveContract;
|
||||
if (primitiveContract != null)
|
||||
{
|
||||
escape = false;
|
||||
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
|
||||
JsonConvert.WriteDateTimeString(sw, (DateTime)key, writer.DateFormatHandling, writer.DateFormatString, writer.Culture);
|
||||
return sw.ToString();
|
||||
}
|
||||
if (primitiveContract.TypeCode == PrimitiveTypeCode.DateTime || primitiveContract.TypeCode == PrimitiveTypeCode.DateTimeNullable)
|
||||
{
|
||||
escape = false;
|
||||
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
|
||||
JsonConvert.WriteDateTimeString(sw, (DateTime)key, writer.DateFormatHandling, writer.DateFormatString, writer.Culture);
|
||||
return sw.ToString();
|
||||
}
|
||||
#if !NET20
|
||||
else if (key is DateTimeOffset)
|
||||
{
|
||||
escape = false;
|
||||
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
|
||||
JsonConvert.WriteDateTimeOffsetString(sw, (DateTimeOffset)key, writer.DateFormatHandling, writer.DateFormatString, writer.Culture);
|
||||
return sw.ToString();
|
||||
}
|
||||
else if (primitiveContract.TypeCode == PrimitiveTypeCode.DateTimeOffset || primitiveContract.TypeCode == PrimitiveTypeCode.DateTimeOffsetNullable)
|
||||
{
|
||||
escape = false;
|
||||
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
|
||||
JsonConvert.WriteDateTimeOffsetString(sw, (DateTimeOffset)key, writer.DateFormatHandling, writer.DateFormatString, writer.Culture);
|
||||
return sw.ToString();
|
||||
}
|
||||
#endif
|
||||
else if (ConvertUtils.IsConvertible(key))
|
||||
{
|
||||
escape = true;
|
||||
return Convert.ToString(key, CultureInfo.InvariantCulture);
|
||||
else
|
||||
{
|
||||
escape = true;
|
||||
return Convert.ToString(key, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
else if (TryConvertToString(key, key.GetType(), out propertyName))
|
||||
{
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.ComponentModel;
|
||||
#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE)
|
||||
@@ -38,181 +39,176 @@ using Newtonsoft.Json.Utilities.LinqBridge;
|
||||
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
|
||||
using System.Data.SqlTypes;
|
||||
#endif
|
||||
#if NETFX_CORE || PORTABLE
|
||||
using IConvertible = Newtonsoft.Json.Utilities.Convertible;
|
||||
#endif
|
||||
|
||||
namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
#if NETFX_CORE || PORTABLE
|
||||
internal class Convertible
|
||||
internal enum PrimitiveTypeCode
|
||||
{
|
||||
private object _underlyingValue;
|
||||
|
||||
public Convertible(object o)
|
||||
{
|
||||
_underlyingValue = o;
|
||||
}
|
||||
|
||||
public TypeCode GetTypeCode()
|
||||
{
|
||||
return ConvertUtils.GetTypeCode(_underlyingValue);
|
||||
}
|
||||
|
||||
public bool ToBoolean(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToBoolean(_underlyingValue, provider);
|
||||
}
|
||||
public byte ToByte(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToByte(_underlyingValue, provider);
|
||||
}
|
||||
public char ToChar(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToChar(_underlyingValue, provider);
|
||||
}
|
||||
public DateTime ToDateTime(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToDateTime(_underlyingValue, provider);
|
||||
}
|
||||
public decimal ToDecimal(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToDecimal(_underlyingValue, provider);
|
||||
}
|
||||
public double ToDouble(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToDouble(_underlyingValue, provider);
|
||||
}
|
||||
public short ToInt16(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToInt16(_underlyingValue, provider);
|
||||
}
|
||||
public int ToInt32(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToInt32(_underlyingValue, provider);
|
||||
}
|
||||
public long ToInt64(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToInt64(_underlyingValue, provider);
|
||||
}
|
||||
public sbyte ToSByte(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToSByte(_underlyingValue, provider);
|
||||
}
|
||||
public float ToSingle(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToSingle(_underlyingValue, provider);
|
||||
}
|
||||
public string ToString(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToString(_underlyingValue, provider);
|
||||
}
|
||||
public object ToType(Type conversionType, IFormatProvider provider)
|
||||
{
|
||||
return Convert.ChangeType(_underlyingValue, conversionType, provider);
|
||||
}
|
||||
public ushort ToUInt16(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToUInt16(_underlyingValue, provider);
|
||||
}
|
||||
public uint ToUInt32(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToUInt32(_underlyingValue, provider);
|
||||
}
|
||||
public ulong ToUInt64(IFormatProvider provider)
|
||||
{
|
||||
return Convert.ToUInt64(_underlyingValue, provider);
|
||||
}
|
||||
}
|
||||
Empty,
|
||||
Object,
|
||||
Char,
|
||||
CharNullable,
|
||||
Boolean,
|
||||
BooleanNullable,
|
||||
SByte,
|
||||
SByteNullable,
|
||||
Int16,
|
||||
Int16Nullable,
|
||||
UInt16,
|
||||
UInt16Nullable,
|
||||
Int32,
|
||||
Int32Nullable,
|
||||
Byte,
|
||||
ByteNullable,
|
||||
UInt32,
|
||||
UInt32Nullable,
|
||||
Int64,
|
||||
Int64Nullable,
|
||||
UInt64,
|
||||
UInt64Nullable,
|
||||
Single,
|
||||
SingleNullable,
|
||||
Double,
|
||||
DoubleNullable,
|
||||
DateTime,
|
||||
DateTimeNullable,
|
||||
#if !NET20
|
||||
DateTimeOffset,
|
||||
DateTimeOffsetNullable,
|
||||
#endif
|
||||
Decimal,
|
||||
DecimalNullable,
|
||||
Guid,
|
||||
GuidNullable,
|
||||
TimeSpan,
|
||||
TimeSpanNullable,
|
||||
#if !(PORTABLE || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT)
|
||||
BigInteger,
|
||||
BigIntegerNullable,
|
||||
#endif
|
||||
Uri,
|
||||
String,
|
||||
Bytes,
|
||||
DBNull
|
||||
}
|
||||
|
||||
internal class TypeInformation
|
||||
{
|
||||
public Type Type { get; set; }
|
||||
public PrimitiveTypeCode TypeCode { get; set; }
|
||||
}
|
||||
|
||||
internal static class ConvertUtils
|
||||
{
|
||||
public static TypeCode GetTypeCode(this IConvertible convertible)
|
||||
{
|
||||
#if !(NETFX_CORE || PORTABLE)
|
||||
return convertible.GetTypeCode();
|
||||
#else
|
||||
return GetTypeCode((object)convertible);
|
||||
private static readonly Dictionary<Type, PrimitiveTypeCode> TypeCodeMap =
|
||||
new Dictionary<Type, PrimitiveTypeCode>
|
||||
{
|
||||
{ typeof(char), PrimitiveTypeCode.Char },
|
||||
{ typeof(char?), PrimitiveTypeCode.CharNullable },
|
||||
{ typeof(bool), PrimitiveTypeCode.Boolean },
|
||||
{ typeof(bool?), PrimitiveTypeCode.BooleanNullable },
|
||||
{ typeof(sbyte), PrimitiveTypeCode.SByte },
|
||||
{ typeof(sbyte?), PrimitiveTypeCode.SByteNullable },
|
||||
{ typeof(short), PrimitiveTypeCode.Int16 },
|
||||
{ typeof(short?), PrimitiveTypeCode.Int16Nullable },
|
||||
{ typeof(ushort), PrimitiveTypeCode.UInt16 },
|
||||
{ typeof(ushort?), PrimitiveTypeCode.UInt16Nullable },
|
||||
{ typeof(int), PrimitiveTypeCode.Int32 },
|
||||
{ typeof(int?), PrimitiveTypeCode.Int32Nullable },
|
||||
{ typeof(byte), PrimitiveTypeCode.Byte },
|
||||
{ typeof(byte?), PrimitiveTypeCode.ByteNullable },
|
||||
{ typeof(uint), PrimitiveTypeCode.UInt32 },
|
||||
{ typeof(uint?), PrimitiveTypeCode.UInt32Nullable },
|
||||
{ typeof(long), PrimitiveTypeCode.Int64 },
|
||||
{ typeof(long?), PrimitiveTypeCode.Int64Nullable },
|
||||
{ typeof(ulong), PrimitiveTypeCode.UInt64 },
|
||||
{ typeof(ulong?), PrimitiveTypeCode.UInt64Nullable },
|
||||
{ typeof(float), PrimitiveTypeCode.Single },
|
||||
{ typeof(float?), PrimitiveTypeCode.SingleNullable },
|
||||
{ typeof(double), PrimitiveTypeCode.Double },
|
||||
{ typeof(double?), PrimitiveTypeCode.DoubleNullable },
|
||||
{ typeof(DateTime), PrimitiveTypeCode.DateTime },
|
||||
{ typeof(DateTime?), PrimitiveTypeCode.DateTimeNullable },
|
||||
#if !NET20
|
||||
{ typeof(DateTimeOffset), PrimitiveTypeCode.DateTimeOffset },
|
||||
{ typeof(DateTimeOffset?), PrimitiveTypeCode.DateTimeOffsetNullable },
|
||||
#endif
|
||||
}
|
||||
|
||||
public static TypeCode GetTypeCode(object o)
|
||||
{
|
||||
#if !(NETFX_CORE || PORTABLE)
|
||||
return System.Convert.GetTypeCode(o);
|
||||
#else
|
||||
return GetTypeCode(o.GetType());
|
||||
{ typeof(decimal), PrimitiveTypeCode.Decimal },
|
||||
{ typeof(decimal?), PrimitiveTypeCode.DecimalNullable },
|
||||
{ typeof(Guid), PrimitiveTypeCode.Guid },
|
||||
{ typeof(Guid?), PrimitiveTypeCode.GuidNullable },
|
||||
{ typeof(TimeSpan), PrimitiveTypeCode.TimeSpan },
|
||||
{ typeof(TimeSpan?), PrimitiveTypeCode.TimeSpanNullable },
|
||||
#if !(PORTABLE || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT)
|
||||
{ typeof(BigInteger), PrimitiveTypeCode.BigInteger },
|
||||
{ typeof(BigInteger?), PrimitiveTypeCode.BigIntegerNullable },
|
||||
#endif
|
||||
}
|
||||
{ typeof(Uri), PrimitiveTypeCode.Uri },
|
||||
{ typeof(string), PrimitiveTypeCode.String },
|
||||
{ typeof(byte[]), PrimitiveTypeCode.Bytes },
|
||||
#if !(PORTABLE || NETFX_CORE)
|
||||
{ typeof(DBNull), PrimitiveTypeCode.DBNull }
|
||||
#endif
|
||||
};
|
||||
|
||||
public static TypeCode GetTypeCode(Type t)
|
||||
private static readonly List<TypeInformation> PrimitiveTypeCodes = new List<TypeInformation>
|
||||
{
|
||||
new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.Empty },
|
||||
new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.Object },
|
||||
new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.DBNull },
|
||||
new TypeInformation { Type = typeof(bool), TypeCode = PrimitiveTypeCode.Boolean },
|
||||
new TypeInformation { Type = typeof(char), TypeCode = PrimitiveTypeCode.Char },
|
||||
new TypeInformation { Type = typeof(sbyte), TypeCode = PrimitiveTypeCode.SByte },
|
||||
new TypeInformation { Type = typeof(byte), TypeCode = PrimitiveTypeCode.Byte },
|
||||
new TypeInformation { Type = typeof(short), TypeCode = PrimitiveTypeCode.Int16 },
|
||||
new TypeInformation { Type = typeof(ushort), TypeCode = PrimitiveTypeCode.UInt16 },
|
||||
new TypeInformation { Type = typeof(int), TypeCode = PrimitiveTypeCode.Int32 },
|
||||
new TypeInformation { Type = typeof(uint), TypeCode = PrimitiveTypeCode.UInt32 },
|
||||
new TypeInformation { Type = typeof(long), TypeCode = PrimitiveTypeCode.Int64 },
|
||||
new TypeInformation { Type = typeof(ulong), TypeCode = PrimitiveTypeCode.UInt64 },
|
||||
new TypeInformation { Type = typeof(float), TypeCode = PrimitiveTypeCode.Single },
|
||||
new TypeInformation { Type = typeof(double), TypeCode = PrimitiveTypeCode.Double },
|
||||
new TypeInformation { Type = typeof(decimal), TypeCode = PrimitiveTypeCode.Decimal },
|
||||
new TypeInformation { Type = typeof(DateTime), TypeCode = PrimitiveTypeCode.DateTime },
|
||||
new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.Empty }, // no 17 in TypeCode for some reason
|
||||
new TypeInformation { Type = typeof(string), TypeCode = PrimitiveTypeCode.String }
|
||||
};
|
||||
|
||||
public static PrimitiveTypeCode GetTypeCode(Type t)
|
||||
{
|
||||
#if !(NETFX_CORE || PORTABLE)
|
||||
return Type.GetTypeCode(t);
|
||||
#else
|
||||
if (t == typeof(bool))
|
||||
return TypeCode.Boolean;
|
||||
if (t == typeof(byte))
|
||||
return TypeCode.Byte;
|
||||
if (t == typeof(char))
|
||||
return TypeCode.Char;
|
||||
if (t == typeof(DateTime))
|
||||
return TypeCode.DateTime;
|
||||
if (t == typeof(decimal))
|
||||
return TypeCode.Decimal;
|
||||
if (t == typeof(double))
|
||||
return TypeCode.Double;
|
||||
if (t == typeof(short))
|
||||
return TypeCode.Int16;
|
||||
if (t == typeof(int))
|
||||
return TypeCode.Int32;
|
||||
if (t == typeof(long))
|
||||
return TypeCode.Int64;
|
||||
if (t == typeof(sbyte))
|
||||
return TypeCode.SByte;
|
||||
if (t == typeof(float))
|
||||
return TypeCode.Single;
|
||||
if (t == typeof(string))
|
||||
return TypeCode.String;
|
||||
if (t == typeof(ushort))
|
||||
return TypeCode.UInt16;
|
||||
if (t == typeof(uint))
|
||||
return TypeCode.UInt32;
|
||||
if (t == typeof(ulong))
|
||||
return TypeCode.UInt64;
|
||||
PrimitiveTypeCode typeCode;
|
||||
if (TypeCodeMap.TryGetValue(t, out typeCode))
|
||||
return typeCode;
|
||||
|
||||
if (t.IsEnum())
|
||||
return GetTypeCode(Enum.GetUnderlyingType(t));
|
||||
|
||||
return TypeCode.Object;
|
||||
#endif
|
||||
// performance?
|
||||
if (ReflectionUtils.IsNullableType(t))
|
||||
{
|
||||
Type nonNullable = Nullable.GetUnderlyingType(t);
|
||||
if (nonNullable.IsEnum())
|
||||
{
|
||||
Type nullableUnderlyingType = ReflectionUtils.MakeGenericType(typeof (Nullable<>), Enum.GetUnderlyingType(nonNullable));
|
||||
return GetTypeCode(nullableUnderlyingType);
|
||||
}
|
||||
}
|
||||
|
||||
return PrimitiveTypeCode.Object;
|
||||
}
|
||||
|
||||
public static IConvertible ToConvertible(object o)
|
||||
public static PrimitiveTypeCode GetTypeCode(object o)
|
||||
{
|
||||
#if !(NETFX_CORE || PORTABLE)
|
||||
return o as IConvertible;
|
||||
#else
|
||||
if (!IsConvertible(o))
|
||||
return null;
|
||||
|
||||
return new IConvertible(o);
|
||||
#endif
|
||||
return GetTypeCode(o.GetType());
|
||||
}
|
||||
|
||||
public static bool IsConvertible(object o)
|
||||
#if !(NETFX_CORE || PORTABLE)
|
||||
public static TypeInformation GetTypeInformation(IConvertible convertable)
|
||||
{
|
||||
#if !(NETFX_CORE || PORTABLE)
|
||||
return o is IConvertible;
|
||||
#else
|
||||
if (o == null)
|
||||
return false;
|
||||
|
||||
return (
|
||||
o is bool || o is byte || o is char || o is DateTime || o is decimal || o is double || o is short || o is int ||
|
||||
o is long || o is sbyte || o is float || o is string || o is ushort || o is uint || o is ulong || o is Enum);
|
||||
#endif
|
||||
TypeInformation typeInformation = PrimitiveTypeCodes[(int) convertable.GetTypeCode()];
|
||||
return typeInformation;
|
||||
}
|
||||
#endif
|
||||
|
||||
public static bool IsConvertible(Type t)
|
||||
{
|
||||
@@ -328,10 +324,15 @@ namespace Newtonsoft.Json.Utilities
|
||||
return (float) i;
|
||||
if (targetType == typeof (ulong))
|
||||
return (ulong) i;
|
||||
if (IsConvertible(targetType))
|
||||
return System.Convert.ChangeType((long) i, targetType, CultureInfo.InvariantCulture);
|
||||
|
||||
throw new InvalidOperationException("Can not convert from BigInteger to {0}.".FormatWith(CultureInfo.InvariantCulture, targetType));
|
||||
try
|
||||
{
|
||||
return System.Convert.ChangeType((long)i, targetType, CultureInfo.InvariantCulture);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException("Can not convert from BigInteger to {0}.".FormatWith(CultureInfo.InvariantCulture, targetType), ex);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -357,7 +358,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
return initialValue;
|
||||
|
||||
// use Convert.ChangeType if both types are IConvertible
|
||||
if (ConvertUtils.IsConvertible(initialValue) && ConvertUtils.IsConvertible(targetType))
|
||||
if (ConvertUtils.IsConvertible(initialValue.GetType()) && ConvertUtils.IsConvertible(targetType))
|
||||
{
|
||||
if (targetType.IsEnum())
|
||||
{
|
||||
@@ -550,14 +551,14 @@ namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
switch (GetTypeCode(value))
|
||||
{
|
||||
case TypeCode.SByte:
|
||||
case TypeCode.Byte:
|
||||
case TypeCode.Int16:
|
||||
case TypeCode.UInt16:
|
||||
case TypeCode.Int32:
|
||||
case TypeCode.UInt32:
|
||||
case TypeCode.Int64:
|
||||
case TypeCode.UInt64:
|
||||
case PrimitiveTypeCode.SByte:
|
||||
case PrimitiveTypeCode.Byte:
|
||||
case PrimitiveTypeCode.Int16:
|
||||
case PrimitiveTypeCode.UInt16:
|
||||
case PrimitiveTypeCode.Int32:
|
||||
case PrimitiveTypeCode.UInt32:
|
||||
case PrimitiveTypeCode.Int64:
|
||||
case PrimitiveTypeCode.UInt64:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -25,15 +25,13 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters;
|
||||
using System.Text;
|
||||
#if NETFX_CORE
|
||||
using IConvertible = Newtonsoft.Json.Utilities.Convertible;
|
||||
#endif
|
||||
#if NETFX_CORE || PORTABLE
|
||||
using ICustomAttributeProvider = Newtonsoft.Json.Utilities.CustomAttributeProvider;
|
||||
#endif
|
||||
@@ -70,29 +68,6 @@ namespace Newtonsoft.Json.Utilities
|
||||
get { return _underlyingObject; }
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (NETFX_CORE || PORTABLE)
|
||||
internal enum TypeCode
|
||||
{
|
||||
Empty,
|
||||
Object,
|
||||
String,
|
||||
Char,
|
||||
Boolean,
|
||||
SByte,
|
||||
Int16,
|
||||
UInt16,
|
||||
Int32,
|
||||
Byte,
|
||||
UInt32,
|
||||
Int64,
|
||||
UInt64,
|
||||
Single,
|
||||
Double,
|
||||
DateTime,
|
||||
Decimal
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum BindingFlags
|
||||
@@ -985,37 +960,35 @@ namespace Newtonsoft.Json.Utilities
|
||||
|
||||
switch (ConvertUtils.GetTypeCode(type))
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
case PrimitiveTypeCode.Boolean:
|
||||
return false;
|
||||
case TypeCode.Char:
|
||||
case TypeCode.SByte:
|
||||
case TypeCode.Byte:
|
||||
case TypeCode.Int16:
|
||||
case TypeCode.UInt16:
|
||||
case TypeCode.Int32:
|
||||
case TypeCode.UInt32:
|
||||
case PrimitiveTypeCode.Char:
|
||||
case PrimitiveTypeCode.SByte:
|
||||
case PrimitiveTypeCode.Byte:
|
||||
case PrimitiveTypeCode.Int16:
|
||||
case PrimitiveTypeCode.UInt16:
|
||||
case PrimitiveTypeCode.Int32:
|
||||
case PrimitiveTypeCode.UInt32:
|
||||
return 0;
|
||||
case TypeCode.Int64:
|
||||
case TypeCode.UInt64:
|
||||
case PrimitiveTypeCode.Int64:
|
||||
case PrimitiveTypeCode.UInt64:
|
||||
return 0L;
|
||||
case TypeCode.Single:
|
||||
case PrimitiveTypeCode.Single:
|
||||
return 0f;
|
||||
case TypeCode.Double:
|
||||
case PrimitiveTypeCode.Double:
|
||||
return 0.0;
|
||||
case TypeCode.Decimal:
|
||||
case PrimitiveTypeCode.Decimal:
|
||||
return 0m;
|
||||
case TypeCode.DateTime:
|
||||
case PrimitiveTypeCode.DateTime:
|
||||
return new DateTime();
|
||||
case PrimitiveTypeCode.BigInteger:
|
||||
return new BigInteger();
|
||||
case PrimitiveTypeCode.Guid:
|
||||
return new Guid();
|
||||
case PrimitiveTypeCode.DateTimeOffset:
|
||||
return new DateTimeOffset();
|
||||
}
|
||||
|
||||
if (type == typeof(Guid))
|
||||
return new Guid();
|
||||
|
||||
#if !NET20
|
||||
if (type == typeof(DateTimeOffset))
|
||||
return new DateTimeOffset();
|
||||
#endif
|
||||
|
||||
if (IsNullable(type))
|
||||
return null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user