-Added JsonConverterAttribute. Can be placed on classes and members. Priority is member attribute -> class attribute -> serializer argument converters
-Added DateTimeFormat to IsoDateTimeConverter to customize format -Changed IConvertible casting to the ToXXXX methods in JsonSerializer
This commit is contained in:
@@ -70,6 +70,9 @@
|
||||
<Compile Include="..\Newtonsoft.Json\JsonConverter.cs">
|
||||
<Link>JsonConverter.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Newtonsoft.Json\JsonConverterAttribute.cs">
|
||||
<Link>JsonConverterAttribute.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Newtonsoft.Json\JsonConverterCollection.cs">
|
||||
<Link>JsonConverterCollection.cs</Link>
|
||||
</Compile>
|
||||
|
||||
@@ -54,6 +54,24 @@ namespace Newtonsoft.Json.Tests.Converters
|
||||
Assert.AreEqual(@"""2000-12-15T22:11:03.0550000" + d.GetLocalOffset() + @"""", result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializeFormattedDateTime()
|
||||
{
|
||||
IsoDateTimeConverter converter = new IsoDateTimeConverter() { DateTimeFormat = "F" };
|
||||
|
||||
DateTime d = new DateTime(2000, 12, 15, 22, 11, 3, 0, DateTimeKind.Utc);
|
||||
string result;
|
||||
|
||||
result = JavaScriptConvert.SerializeObject(d, converter);
|
||||
Assert.AreEqual(@"""Friday, 15 December 2000 22:11:03""", result);
|
||||
|
||||
Assert.AreEqual(d, JavaScriptConvert.DeserializeObject<DateTime>(result, converter));
|
||||
|
||||
d = new DateTime(2000, 12, 15, 22, 11, 3, 0, DateTimeKind.Local);
|
||||
result = JavaScriptConvert.SerializeObject(d, converter);
|
||||
Assert.AreEqual(@"""Friday, 15 December 2000 22:11:03""", result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializeDateTimeOffset()
|
||||
{
|
||||
|
||||
@@ -37,6 +37,8 @@ using Newtonsoft.Json.Linq;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
@@ -1097,5 +1099,170 @@ keyword such as type of business.""
|
||||
Assert.AreEqual("Param1", deserialized.Param1);
|
||||
Assert.AreEqual("Param2", deserialized.Param2);
|
||||
}
|
||||
|
||||
public class MemberConverterPrecedenceClassConverter : ConverterPrecedenceClassConverter
|
||||
{
|
||||
public override string ConverterType
|
||||
{
|
||||
get { return "Member"; }
|
||||
}
|
||||
}
|
||||
|
||||
public class ClassConverterPrecedenceClassConverter : ConverterPrecedenceClassConverter
|
||||
{
|
||||
public override string ConverterType
|
||||
{
|
||||
get { return "Class"; }
|
||||
}
|
||||
}
|
||||
|
||||
public class ArgumentConverterPrecedenceClassConverter : ConverterPrecedenceClassConverter
|
||||
{
|
||||
public override string ConverterType
|
||||
{
|
||||
get { return "Argument"; }
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ConverterPrecedenceClassConverter : JsonConverter
|
||||
{
|
||||
public abstract string ConverterType { get; }
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value)
|
||||
{
|
||||
ConverterPrecedenceClass c = (ConverterPrecedenceClass)value;
|
||||
|
||||
JToken j = new JArray(ConverterType, c.TestValue);
|
||||
|
||||
j.WriteTo(writer);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType)
|
||||
{
|
||||
JToken j = JArray.Load(reader);
|
||||
|
||||
string converter = (string)j[0];
|
||||
if (converter != ConverterType)
|
||||
throw new Exception("Serialize converter {0} and deserialize converter {1} do not match.".FormatWith(CultureInfo.InvariantCulture, converter, ConverterType));
|
||||
|
||||
string testValue = (string)j[1];
|
||||
return new ConverterPrecedenceClass(testValue);
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return (objectType == typeof(ConverterPrecedenceClass));
|
||||
}
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(ClassConverterPrecedenceClassConverter))]
|
||||
public class ConverterPrecedenceClass
|
||||
{
|
||||
public string TestValue { get; set; }
|
||||
|
||||
public ConverterPrecedenceClass(string testValue)
|
||||
{
|
||||
TestValue = testValue;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializerShouldUseClassConverter()
|
||||
{
|
||||
ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!");
|
||||
|
||||
string json = JavaScriptConvert.SerializeObject(c1);
|
||||
Assert.AreEqual(@"[""Class"",""!Test!""]", json);
|
||||
|
||||
ConverterPrecedenceClass c2 = JavaScriptConvert.DeserializeObject<ConverterPrecedenceClass>(json);
|
||||
|
||||
Assert.AreEqual("!Test!", c2.TestValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializerShouldUseClassConverterOverArgumentConverter()
|
||||
{
|
||||
ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!");
|
||||
|
||||
string json = JavaScriptConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter());
|
||||
Assert.AreEqual(@"[""Class"",""!Test!""]", json);
|
||||
|
||||
ConverterPrecedenceClass c2 = JavaScriptConvert.DeserializeObject<ConverterPrecedenceClass>(json, new ArgumentConverterPrecedenceClassConverter());
|
||||
|
||||
Assert.AreEqual("!Test!", c2.TestValue);
|
||||
}
|
||||
|
||||
public class MemberConverterClass
|
||||
{
|
||||
public DateTime DefaultConverter { get; set; }
|
||||
[JsonConverter(typeof(IsoDateTimeConverter))]
|
||||
public DateTime MemberConverter { get; set; }
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializerShouldUseMemberConverter()
|
||||
{
|
||||
DateTime testDate = new DateTime(JavaScriptConvert.InitialJavaScriptDateTicks, DateTimeKind.Utc);
|
||||
MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
|
||||
|
||||
string json = JavaScriptConvert.SerializeObject(m1);
|
||||
Assert.AreEqual(@"{""DefaultConverter"":""\/Date(0)\/"",""MemberConverter"":""1970-01-01T00:00:00.0000000Z""}", json);
|
||||
|
||||
MemberConverterClass m2 = JavaScriptConvert.DeserializeObject<MemberConverterClass>(json);
|
||||
|
||||
Assert.AreEqual(testDate, m2.DefaultConverter);
|
||||
Assert.AreEqual(testDate, m2.MemberConverter);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializerShouldUseMemberConverterOverArgumentConverter()
|
||||
{
|
||||
DateTime testDate = new DateTime(JavaScriptConvert.InitialJavaScriptDateTicks, DateTimeKind.Utc);
|
||||
MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
|
||||
|
||||
string json = JavaScriptConvert.SerializeObject(m1, new JavaScriptDateTimeConverter());
|
||||
Assert.AreEqual(@"{""DefaultConverter"":new Date(0),""MemberConverter"":""1970-01-01T00:00:00.0000000Z""}", json);
|
||||
|
||||
MemberConverterClass m2 = JavaScriptConvert.DeserializeObject<MemberConverterClass>(json, new JavaScriptDateTimeConverter());
|
||||
|
||||
Assert.AreEqual(testDate, m2.DefaultConverter);
|
||||
Assert.AreEqual(testDate, m2.MemberConverter);
|
||||
}
|
||||
|
||||
public class ClassAndMemberConverterClass
|
||||
{
|
||||
public ConverterPrecedenceClass DefaultConverter { get; set; }
|
||||
[JsonConverter(typeof(MemberConverterPrecedenceClassConverter))]
|
||||
public ConverterPrecedenceClass MemberConverter { get; set; }
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializerShouldUseMemberConverterOverClassAndArgumentConverter()
|
||||
{
|
||||
ClassAndMemberConverterClass c1 = new ClassAndMemberConverterClass();
|
||||
c1.DefaultConverter = new ConverterPrecedenceClass("DefaultConverterValue");
|
||||
c1.MemberConverter = new ConverterPrecedenceClass("MemberConverterValue");
|
||||
|
||||
string json = JavaScriptConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter());
|
||||
Assert.AreEqual(@"{""DefaultConverter"":[""Class"",""DefaultConverterValue""],""MemberConverter"":[""Member"",""MemberConverterValue""]}", json);
|
||||
|
||||
ClassAndMemberConverterClass c2 = JavaScriptConvert.DeserializeObject<ClassAndMemberConverterClass>(json, new ArgumentConverterPrecedenceClassConverter());
|
||||
|
||||
Assert.AreEqual("DefaultConverterValue", c2.DefaultConverter.TestValue);
|
||||
Assert.AreEqual("MemberConverterValue", c2.MemberConverter.TestValue);
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(IsoDateTimeConverter))]
|
||||
public class IncompatibleJsonAttributeClass
|
||||
{
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "JsonConverter IsoDateTimeConverter on Newtonsoft.Json.Tests.JsonSerializerTest+IncompatibleJsonAttributeClass is not compatible with member type IncompatibleJsonAttributeClass.")]
|
||||
public void IncompatibleJsonAttributeShouldThrow()
|
||||
{
|
||||
IncompatibleJsonAttributeClass c = new IncompatibleJsonAttributeClass();
|
||||
JavaScriptConvert.SerializeObject(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,9 +12,10 @@ namespace Newtonsoft.Json.Converters
|
||||
/// </summary>
|
||||
public class IsoDateTimeConverter : JsonConverter
|
||||
{
|
||||
private const string DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK";
|
||||
private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK";
|
||||
|
||||
private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;
|
||||
private string _dateTimeFormat = DefaultDateTimeFormat;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date time styles used when converting a date to and from JSON.
|
||||
@@ -26,6 +27,16 @@ namespace Newtonsoft.Json.Converters
|
||||
set { _dateTimeStyles = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date time format used when converting a date to and fromm JSON.
|
||||
/// </summary>
|
||||
/// <value>The date time format used when converting a date to and from JSON.</value>
|
||||
public string DateTimeFormat
|
||||
{
|
||||
get { return _dateTimeFormat; }
|
||||
set { _dateTimeFormat = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the JSON representation of the object.
|
||||
/// </summary>
|
||||
@@ -43,7 +54,7 @@ namespace Newtonsoft.Json.Converters
|
||||
|| (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
|
||||
dateTime = dateTime.ToUniversalTime();
|
||||
|
||||
text = dateTime.ToString(DateTimeFormat, CultureInfo.InvariantCulture);
|
||||
text = dateTime.ToString(_dateTimeFormat, CultureInfo.InvariantCulture);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -52,7 +63,7 @@ namespace Newtonsoft.Json.Converters
|
||||
|| (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
|
||||
dateTimeOffset = dateTimeOffset.ToUniversalTime();
|
||||
|
||||
text = dateTimeOffset.ToString(DateTimeFormat, CultureInfo.InvariantCulture);
|
||||
text = dateTimeOffset.ToString(_dateTimeFormat, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
writer.WriteValue(text);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class, AllowMultiple = false)]
|
||||
public class JsonConverterAttribute : Attribute
|
||||
{
|
||||
private readonly Type _converterType;
|
||||
|
||||
public Type ConverterType
|
||||
{
|
||||
get { return _converterType; }
|
||||
}
|
||||
|
||||
public JsonConverterAttribute(Type converterType)
|
||||
{
|
||||
if (converterType == null)
|
||||
throw new ArgumentNullException("converterType");
|
||||
|
||||
_converterType = converterType;
|
||||
}
|
||||
|
||||
internal JsonConverter CreateJsonConverterInstance()
|
||||
{
|
||||
try
|
||||
{
|
||||
return (JsonConverter)Activator.CreateInstance(_converterType);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Error creating {0}".FormatWith(CultureInfo.InvariantCulture, _converterType), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,7 +166,7 @@ namespace Newtonsoft.Json
|
||||
return null;
|
||||
|
||||
if (objectType != null)
|
||||
return CreateObject(reader, objectType, null);
|
||||
return CreateObject(reader, objectType, null, null);
|
||||
else
|
||||
return CreateJToken(reader);
|
||||
}
|
||||
@@ -195,14 +195,31 @@ namespace Newtonsoft.Json
|
||||
return token;
|
||||
}
|
||||
|
||||
private object CreateObject(JsonReader reader, Type objectType, object existingValue)
|
||||
private bool HasClassConverter(Type objectType, out JsonConverter converter)
|
||||
{
|
||||
if (objectType == null)
|
||||
throw new ArgumentNullException("objectType");
|
||||
|
||||
converter = GetConverter(objectType, objectType);
|
||||
return (converter != null);
|
||||
}
|
||||
|
||||
private object CreateObject(JsonReader reader, Type objectType, object existingValue, JsonConverter memberConverter)
|
||||
{
|
||||
_level++;
|
||||
|
||||
object value;
|
||||
JsonConverter converter;
|
||||
|
||||
if (HasMatchingConverter(objectType, out converter))
|
||||
if (memberConverter != null)
|
||||
{
|
||||
return memberConverter.ReadJson(reader, objectType);
|
||||
}
|
||||
else if (objectType != null && HasClassConverter(objectType, out converter))
|
||||
{
|
||||
return converter.ReadJson(reader, objectType);
|
||||
}
|
||||
else if (objectType != null && HasMatchingConverter(objectType, out converter))
|
||||
{
|
||||
return converter.ReadJson(reader, objectType);
|
||||
}
|
||||
@@ -338,7 +355,10 @@ namespace Newtonsoft.Json
|
||||
|
||||
bool readable = ReflectionUtils.CanReadMemberValue(member);
|
||||
bool writable = ReflectionUtils.CanSetMemberValue(member);
|
||||
MemberMapping memberMapping = new MemberMapping(mappedName, member, ignored, readable, writable);
|
||||
|
||||
JsonConverter memberConverter = GetConverter(member, ReflectionUtils.GetMemberUnderlyingType(member));
|
||||
|
||||
MemberMapping memberMapping = new MemberMapping(mappedName, member, ignored, readable, writable, memberConverter);
|
||||
|
||||
memberMappings.AddMapping(memberMapping);
|
||||
}
|
||||
@@ -366,6 +386,23 @@ namespace Newtonsoft.Json
|
||||
return objectAttribute.MemberSerialization;
|
||||
}
|
||||
|
||||
private JsonConverter GetConverter(ICustomAttributeProvider attributeProvider, Type targetConvertedType)
|
||||
{
|
||||
JsonConverterAttribute converterAttribute = ReflectionUtils.GetAttribute<JsonConverterAttribute>(attributeProvider, true);
|
||||
|
||||
if (converterAttribute != null)
|
||||
{
|
||||
JsonConverter memberConverter = converterAttribute.CreateJsonConverterInstance();
|
||||
|
||||
if (!memberConverter.CanConvert(targetConvertedType))
|
||||
throw new JsonSerializationException("JsonConverter {0} on {1} is not compatible with member type {2}.".FormatWith(CultureInfo.InvariantCulture, memberConverter.GetType().Name, attributeProvider, targetConvertedType.Name));
|
||||
|
||||
return memberConverter;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void SetObjectMember(JsonReader reader, object target, Type targetType, string memberName)
|
||||
{
|
||||
if (!reader.Read())
|
||||
@@ -402,7 +439,7 @@ namespace Newtonsoft.Json
|
||||
return;
|
||||
}
|
||||
|
||||
value = CreateObject(reader, memberType, (useExistingValue) ? currentValue : null);
|
||||
value = CreateObject(reader, memberType, (useExistingValue) ? currentValue : null, GetConverter(memberMapping.Member, memberType));
|
||||
|
||||
if (_nullValueHandling == NullValueHandling.Ignore && value == null)
|
||||
return;
|
||||
@@ -439,7 +476,7 @@ namespace Newtonsoft.Json
|
||||
object keyValue = EnsureType(reader.Value, dictionaryKeyType);
|
||||
reader.Read();
|
||||
|
||||
dictionary.Add(keyValue, CreateObject(reader, dictionaryValueType, null));
|
||||
dictionary.Add(keyValue, CreateObject(reader, dictionaryValueType, null, null));
|
||||
break;
|
||||
case JsonToken.EndObject:
|
||||
return dictionary;
|
||||
@@ -467,7 +504,7 @@ namespace Newtonsoft.Json
|
||||
case JsonToken.Comment:
|
||||
break;
|
||||
default:
|
||||
object value = CreateObject(reader, listItemType, null);
|
||||
object value = CreateObject(reader, listItemType, null, null);
|
||||
|
||||
list.Add(value);
|
||||
break;
|
||||
@@ -497,6 +534,7 @@ namespace Newtonsoft.Json
|
||||
|
||||
// create a dictionary to put retrieved values into
|
||||
IDictionary<ParameterInfo, object> constructorParameters = c.GetParameters().ToDictionary(p => p, p => (object)null);
|
||||
MemberMappingCollection mappings = GetMemberMappings(objectType);
|
||||
|
||||
bool exit = false;
|
||||
while (!exit && reader.Read())
|
||||
@@ -505,16 +543,21 @@ namespace Newtonsoft.Json
|
||||
{
|
||||
case JsonToken.PropertyName:
|
||||
string memberName = reader.Value.ToString();
|
||||
ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, memberName).Key;
|
||||
|
||||
if (!reader.Read())
|
||||
throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
|
||||
|
||||
if (matchingConstructorParameter != null)
|
||||
constructorParameters[matchingConstructorParameter] = CreateObject(reader, matchingConstructorParameter.ParameterType, null);
|
||||
else
|
||||
reader.Skip();
|
||||
ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, memberName).Key;
|
||||
MemberMapping mapping;
|
||||
|
||||
if (matchingConstructorParameter != null && mappings.TryGetMapping(memberName, out mapping) && !mapping.Ignored)
|
||||
{
|
||||
constructorParameters[matchingConstructorParameter] = CreateObject(reader, matchingConstructorParameter.ParameterType, null, mapping.MemberConverter);
|
||||
}
|
||||
else
|
||||
{
|
||||
// skip token and all child tokens
|
||||
reader.Skip();
|
||||
}
|
||||
break;
|
||||
case JsonToken.EndObject:
|
||||
exit = true;
|
||||
@@ -578,11 +621,11 @@ namespace Newtonsoft.Json
|
||||
if (value is JToken)
|
||||
((JToken)value).WriteTo(jsonWriter, (_converters != null) ? _converters.ToArray() : null);
|
||||
else
|
||||
SerializeValue(jsonWriter, value);
|
||||
SerializeValue(jsonWriter, value, null);
|
||||
}
|
||||
|
||||
|
||||
private void SerializeValue(JsonWriter writer, object value)
|
||||
private void SerializeValue(JsonWriter writer, object value, JsonConverter memberConverter)
|
||||
{
|
||||
JsonConverter converter;
|
||||
|
||||
@@ -590,6 +633,14 @@ namespace Newtonsoft.Json
|
||||
{
|
||||
writer.WriteNull();
|
||||
}
|
||||
else if (memberConverter != null)
|
||||
{
|
||||
memberConverter.WriteJson(writer, value);
|
||||
}
|
||||
else if (HasClassConverter(value.GetType(), out converter))
|
||||
{
|
||||
converter.WriteJson(writer, value);
|
||||
}
|
||||
else if (HasMatchingConverter(value.GetType(), out converter))
|
||||
{
|
||||
converter.WriteJson(writer, value);
|
||||
@@ -601,49 +652,49 @@ namespace Newtonsoft.Json
|
||||
switch (convertible.GetTypeCode())
|
||||
{
|
||||
case TypeCode.String:
|
||||
writer.WriteValue((string)convertible);
|
||||
writer.WriteValue(convertible.ToString(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case TypeCode.Char:
|
||||
writer.WriteValue((char)convertible);
|
||||
writer.WriteValue(convertible.ToChar(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case TypeCode.Boolean:
|
||||
writer.WriteValue((bool)convertible);
|
||||
writer.WriteValue(convertible.ToBoolean(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case TypeCode.SByte:
|
||||
writer.WriteValue((sbyte)convertible);
|
||||
writer.WriteValue(convertible.ToSByte(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case TypeCode.Int16:
|
||||
writer.WriteValue((short)convertible);
|
||||
writer.WriteValue(convertible.ToInt16(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case TypeCode.UInt16:
|
||||
writer.WriteValue((ushort)convertible);
|
||||
writer.WriteValue(convertible.ToUInt16(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case TypeCode.Int32:
|
||||
writer.WriteValue((int)convertible);
|
||||
writer.WriteValue(convertible.ToInt32(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case TypeCode.Byte:
|
||||
writer.WriteValue((byte)convertible);
|
||||
writer.WriteValue(convertible.ToByte(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case TypeCode.UInt32:
|
||||
writer.WriteValue((uint)convertible);
|
||||
writer.WriteValue(convertible.ToUInt32(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case TypeCode.Int64:
|
||||
writer.WriteValue((long)convertible);
|
||||
writer.WriteValue(convertible.ToInt64(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case TypeCode.UInt64:
|
||||
writer.WriteValue((ulong)convertible);
|
||||
writer.WriteValue(convertible.ToUInt64(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case TypeCode.Single:
|
||||
writer.WriteValue((float)convertible);
|
||||
writer.WriteValue(convertible.ToSingle(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case TypeCode.Double:
|
||||
writer.WriteValue((double)convertible);
|
||||
writer.WriteValue(convertible.ToDouble(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case TypeCode.DateTime:
|
||||
writer.WriteValue((DateTime)convertible);
|
||||
writer.WriteValue(convertible.ToDateTime(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case TypeCode.Decimal:
|
||||
writer.WriteValue((decimal)convertible);
|
||||
writer.WriteValue(convertible.ToDecimal(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case TypeCode.DBNull:
|
||||
writer.WriteNull();
|
||||
@@ -688,15 +739,18 @@ namespace Newtonsoft.Json
|
||||
return HasMatchingConverter(_converters, type, out matchingConverter);
|
||||
}
|
||||
|
||||
internal static bool HasMatchingConverter(IList<JsonConverter> converters, Type type, out JsonConverter matchingConverter)
|
||||
internal static bool HasMatchingConverter(IList<JsonConverter> converters, Type objectType, out JsonConverter matchingConverter)
|
||||
{
|
||||
if (objectType == null)
|
||||
throw new ArgumentNullException("objectType");
|
||||
|
||||
if (converters != null)
|
||||
{
|
||||
for (int i = 0; i < converters.Count; i++)
|
||||
{
|
||||
JsonConverter converter = converters[i];
|
||||
|
||||
if (converter.CanConvert(type))
|
||||
if (converter.CanConvert(objectType))
|
||||
{
|
||||
matchingConverter = converter;
|
||||
return true;
|
||||
@@ -708,7 +762,7 @@ namespace Newtonsoft.Json
|
||||
return false;
|
||||
}
|
||||
|
||||
private void WriteMemberInfoProperty(JsonWriter writer, object value, MemberInfo member, string propertyName)
|
||||
private void WriteMemberInfoProperty(JsonWriter writer, object value, MemberInfo member, string propertyName, JsonConverter memberConverter)
|
||||
{
|
||||
if (!ReflectionUtils.IsIndexedProperty(member))
|
||||
{
|
||||
@@ -735,7 +789,7 @@ namespace Newtonsoft.Json
|
||||
}
|
||||
|
||||
writer.WritePropertyName(propertyName ?? member.Name);
|
||||
SerializeValue(writer, memberValue);
|
||||
SerializeValue(writer, memberValue, memberConverter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -772,7 +826,7 @@ namespace Newtonsoft.Json
|
||||
foreach (MemberMapping memberMapping in memberMappings)
|
||||
{
|
||||
if (!memberMapping.Ignored && memberMapping.Readable)
|
||||
WriteMemberInfoProperty(writer, value, memberMapping.Member, memberMapping.MappingName);
|
||||
WriteMemberInfoProperty(writer, value, memberMapping.Member, memberMapping.MappingName, memberMapping.MemberConverter);
|
||||
}
|
||||
|
||||
writer.WriteEndObject();
|
||||
@@ -796,7 +850,7 @@ namespace Newtonsoft.Json
|
||||
|
||||
for (int i = 0; i < values.Count; i++)
|
||||
{
|
||||
SerializeValue(writer, values[i]);
|
||||
SerializeValue(writer, values[i], null);
|
||||
}
|
||||
|
||||
writer.WriteEndArray();
|
||||
@@ -809,7 +863,7 @@ namespace Newtonsoft.Json
|
||||
foreach (DictionaryEntry entry in values)
|
||||
{
|
||||
writer.WritePropertyName(entry.Key.ToString());
|
||||
SerializeValue(writer, entry.Value);
|
||||
SerializeValue(writer, entry.Value, null);
|
||||
}
|
||||
|
||||
writer.WriteEndObject();
|
||||
|
||||
@@ -37,14 +37,16 @@ namespace Newtonsoft.Json
|
||||
private readonly bool _ignored;
|
||||
private readonly bool _readable;
|
||||
private readonly bool _writable;
|
||||
private readonly JsonConverter _memberConverter;
|
||||
|
||||
public MemberMapping(string mappingName, MemberInfo member, bool ignored, bool readable, bool writable)
|
||||
public MemberMapping(string mappingName, MemberInfo member, bool ignored, bool readable, bool writable, JsonConverter memberConverter)
|
||||
{
|
||||
_mappingName = mappingName;
|
||||
_member = member;
|
||||
_ignored = ignored;
|
||||
_readable = readable;
|
||||
_writable = writable;
|
||||
_memberConverter = memberConverter;
|
||||
}
|
||||
|
||||
public string MappingName
|
||||
@@ -71,5 +73,10 @@ namespace Newtonsoft.Json
|
||||
{
|
||||
get { return _writable; }
|
||||
}
|
||||
|
||||
public JsonConverter MemberConverter
|
||||
{
|
||||
get { return _memberConverter; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,5 +63,19 @@ namespace Newtonsoft.Json
|
||||
|
||||
Add(memberMapping);
|
||||
}
|
||||
|
||||
public bool TryGetMapping(string mappingName, out MemberMapping memberMapping)
|
||||
{
|
||||
if (Contains(mappingName))
|
||||
{
|
||||
memberMapping = this[mappingName];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
memberMapping = default(MemberMapping);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,6 +74,7 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="JsonConverterAttribute.cs" />
|
||||
<Compile Include="JsonObjectAttribute.cs" />
|
||||
<Compile Include="MemberSerialization.cs" />
|
||||
<Compile Include="ObjectCreationHandling.cs" />
|
||||
|
||||
Reference in New Issue
Block a user