-Fixed StringEnumConverter to throw a JsonSerializerException like the serializer throws for invalid enums
-Changed Windows Phone and Portable builds to use Microsoft.CSharp.dll directly
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
using Newtonsoft.Json.Converters;
|
||||
#if !NETFX_CORE
|
||||
@@ -334,5 +335,30 @@ namespace Newtonsoft.Json.Tests.Converters
|
||||
EnumClass c = JsonConvert.DeserializeObject<EnumClass>(json, new StringEnumConverter());
|
||||
Assert.IsNull(c.NullableStoreColor2);
|
||||
}
|
||||
|
||||
public void DeserializeInvalidString()
|
||||
{
|
||||
string json = "{ \"Value\" : \"Three\" }";
|
||||
|
||||
ExceptionAssert.Throws<JsonSerializationException>(
|
||||
@"Error converting value ""Three"" to type 'Newtonsoft.Json.Tests.Converters.StringEnumConverterTests+MyEnum'. Path 'Value', line 1, position 19.",
|
||||
() =>
|
||||
{
|
||||
var serializer = new JsonSerializer();
|
||||
serializer.Converters.Add(new StringEnumConverter());
|
||||
serializer.Deserialize<Bucket>(new JsonTextReader(new StringReader(json)));
|
||||
});
|
||||
}
|
||||
|
||||
public class Bucket
|
||||
{
|
||||
public MyEnum Value;
|
||||
}
|
||||
|
||||
public enum MyEnum
|
||||
{
|
||||
Alpha,
|
||||
Beta,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,4 +75,4 @@ using System.Security;
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("4.5.0.0")]
|
||||
[assembly: AssemblyFileVersion("5.0.1.15917")]
|
||||
[assembly: AssemblyFileVersion("5.0.1.15923")]
|
||||
|
||||
@@ -90,6 +90,40 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
[TestFixture]
|
||||
public class JsonSerializerTest : TestFixtureBase
|
||||
{
|
||||
//[DataContract]
|
||||
//public class BaseDataContract1
|
||||
//{
|
||||
// [DataMember(Name = "virtualMember")]
|
||||
// public virtual string VirtualMember { get; set; }
|
||||
|
||||
// [DataMember(Name = "nonVirtualMember")]
|
||||
// public string NonVirtualMember { get; set; }
|
||||
|
||||
// public virtual object NewMember { get; set; }
|
||||
//}
|
||||
|
||||
//public class ChildDataContract1 : BaseDataContract1
|
||||
//{
|
||||
// [DataMember(Name = "NewMember")]
|
||||
// public virtual new string NewMember { get; set; }
|
||||
// public override string VirtualMember { get; set; }
|
||||
// public string AddedMember { get; set; }
|
||||
//}
|
||||
|
||||
//[Test]
|
||||
//public void ChildDataContractTest1()
|
||||
//{
|
||||
// var cc = new ChildDataContract1
|
||||
// {
|
||||
// VirtualMember = "VirtualMember!",
|
||||
// NonVirtualMember = "NonVirtualMember!",
|
||||
// NewMember = "NewMember!"
|
||||
// };
|
||||
|
||||
// string result = JsonConvert.SerializeObject(cc);
|
||||
// Assert.AreEqual(@"{""NewMember"":""NewMember!"",""virtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result);
|
||||
//}
|
||||
|
||||
[Test]
|
||||
public void PersonTypedObjectDeserialization()
|
||||
{
|
||||
@@ -6450,6 +6484,21 @@ Parameter name: value",
|
||||
}", json);
|
||||
}
|
||||
|
||||
#if !(NET20 || NET35)
|
||||
public class IgnoreDataMemberTestClass
|
||||
{
|
||||
[IgnoreDataMember]
|
||||
public int Ignored { get; set; }
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IgnoreDataMemberTest()
|
||||
{
|
||||
string json = JsonConvert.SerializeObject(new IgnoreDataMemberTestClass() { Ignored = int.MaxValue }, Formatting.Indented);
|
||||
Assert.AreEqual(@"{}", json);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !(NET20 || NET35)
|
||||
[Test]
|
||||
public void SerializeDataContractSerializationAttributes()
|
||||
@@ -6462,6 +6511,12 @@ Parameter name: value",
|
||||
IgnoreDataMemberAndDataMemberAttribute = "Value!"
|
||||
};
|
||||
|
||||
//MemoryStream ms = new MemoryStream();
|
||||
//DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(DataContractSerializationAttributesClass));
|
||||
//serializer.WriteObject(ms, dataContract);
|
||||
|
||||
//Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
|
||||
|
||||
string json = JsonConvert.SerializeObject(dataContract, Formatting.Indented);
|
||||
Assert.AreEqual(@"{
|
||||
""DataMemberAttribute"": ""Value!"",
|
||||
|
||||
@@ -111,22 +111,30 @@ namespace Newtonsoft.Json.Converters
|
||||
return null;
|
||||
}
|
||||
|
||||
if (reader.TokenType == JsonToken.String)
|
||||
try
|
||||
{
|
||||
string enumText = reader.Value.ToString();
|
||||
if (enumText == string.Empty && isNullable)
|
||||
return null;
|
||||
if (reader.TokenType == JsonToken.String)
|
||||
{
|
||||
string enumText = reader.Value.ToString();
|
||||
if (enumText == string.Empty && isNullable)
|
||||
return null;
|
||||
|
||||
var map = GetEnumNameMap(t);
|
||||
string resolvedEnumName;
|
||||
map.TryGetBySecond(enumText, out resolvedEnumName);
|
||||
resolvedEnumName = resolvedEnumName ?? enumText;
|
||||
var map = GetEnumNameMap(t);
|
||||
string resolvedEnumName;
|
||||
map.TryGetBySecond(enumText, out resolvedEnumName);
|
||||
resolvedEnumName = resolvedEnumName ?? enumText;
|
||||
|
||||
return Enum.Parse(t, resolvedEnumName, true);
|
||||
return Enum.Parse(t, resolvedEnumName, true);
|
||||
}
|
||||
|
||||
if (reader.TokenType == JsonToken.Integer)
|
||||
return ConvertUtils.ConvertOrCast(reader.Value, CultureInfo.InvariantCulture, t);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw JsonSerializationException.Create(reader, "Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.FormatValueForPrint(reader.Value), objectType), ex);
|
||||
}
|
||||
|
||||
if (reader.TokenType == JsonToken.Integer)
|
||||
return ConvertUtils.ConvertOrCast(reader.Value, CultureInfo.InvariantCulture, t);
|
||||
|
||||
throw JsonSerializationException.Create(reader, "Unexpected token when parsing enum. Expected String or Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
|
||||
}
|
||||
|
||||
@@ -37,8 +37,6 @@
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -90,6 +90,6 @@ using System.Security;
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("4.5.0.0")]
|
||||
[assembly: AssemblyFileVersion("5.0.1.15917")]
|
||||
[assembly: AssemblyFileVersion("5.0.1.15923")]
|
||||
|
||||
[assembly: CLSCompliant(true)]
|
||||
|
||||
@@ -671,24 +671,13 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw JsonSerializationException.Create(reader, "Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, FormatValueForPrint(value), targetType), ex);
|
||||
throw JsonSerializationException.Create(reader, "Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.FormatValueForPrint(value), targetType), ex);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private string FormatValueForPrint(object value)
|
||||
{
|
||||
if (value == null)
|
||||
return "{null}";
|
||||
|
||||
if (value is string)
|
||||
return @"""" + value + @"""";
|
||||
|
||||
return value.ToString();
|
||||
}
|
||||
|
||||
private void SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target)
|
||||
{
|
||||
object currentValue;
|
||||
|
||||
@@ -29,7 +29,11 @@ using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
#if !(PORTABLE || WINDOWS_PHONE)
|
||||
using System.Reflection;
|
||||
#else
|
||||
using Microsoft.CSharp.RuntimeBinder;
|
||||
#endif
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
@@ -41,6 +45,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
internal static class BinderWrapper
|
||||
{
|
||||
#if !(PORTABLE || WINDOWS_PHONE)
|
||||
#if !SILVERLIGHT
|
||||
public const string CSharpAssemblyName = "Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
|
||||
#else
|
||||
@@ -95,9 +100,9 @@ namespace Newtonsoft.Json.Utilities
|
||||
|
||||
private static void CreateMemberCalls()
|
||||
{
|
||||
Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName);
|
||||
Type csharpBinderFlagsType = Type.GetType(CSharpBinderFlagsTypeName);
|
||||
Type binderType = Type.GetType(BinderTypeName);
|
||||
Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName, true);
|
||||
Type csharpBinderFlagsType = Type.GetType(CSharpBinderFlagsTypeName, true);
|
||||
Type binderType = Type.GetType(BinderTypeName, true);
|
||||
|
||||
Type csharpArgumentInfoTypeEnumerableType = typeof (IEnumerable<>).MakeGenericType(csharpArgumentInfoType);
|
||||
|
||||
@@ -107,17 +112,32 @@ namespace Newtonsoft.Json.Utilities
|
||||
MethodInfo setMemberMethod = binderType.GetMethod("SetMember", new[] {csharpBinderFlagsType, typeof (string), typeof (Type), csharpArgumentInfoTypeEnumerableType});
|
||||
_setMemberCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(setMemberMethod);
|
||||
}
|
||||
#endif
|
||||
|
||||
public static CallSiteBinder GetMember(string name, Type context)
|
||||
{
|
||||
#if !(PORTABLE || WINDOWS_PHONE)
|
||||
Init();
|
||||
return (CallSiteBinder) _getMemberCall(null, 0, name, context, _getCSharpArgumentInfoArray);
|
||||
#else
|
||||
return Binder.GetMember(
|
||||
CSharpBinderFlags.None, name, context, new[] {CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)});
|
||||
#endif
|
||||
}
|
||||
|
||||
public static CallSiteBinder SetMember(string name, Type context)
|
||||
{
|
||||
#if !(PORTABLE || WINDOWS_PHONE)
|
||||
Init();
|
||||
return (CallSiteBinder) _setMemberCall(null, 0, name, context, _setCSharpArgumentInfoArray);
|
||||
#else
|
||||
return Binder.SetMember(
|
||||
CSharpBinderFlags.None, name, context, new[]
|
||||
{
|
||||
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
|
||||
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant, null)
|
||||
});
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -183,5 +183,16 @@ namespace Newtonsoft.Json.Utilities
|
||||
localName = qualifiedName.Substring(colonPosition + 1);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string FormatValueForPrint(object value)
|
||||
{
|
||||
if (value == null)
|
||||
return "{null}";
|
||||
|
||||
if (value is string)
|
||||
return @"""" + value + @"""";
|
||||
|
||||
return value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user