-Fixed StringEnumConverter.AllowIntegerValues to reject integer strings

This commit is contained in:
James Newton-King
2016-09-12 17:25:19 +12:00
parent 39ecc359eb
commit 6c272eac6e
3 changed files with 81 additions and 2 deletions
@@ -573,7 +573,54 @@ namespace Newtonsoft.Json.Tests.Converters
Assert.AreEqual(DuplicateNameEnum2.FooBar, o.Value2);
}, "Type 'Newtonsoft.Json.Tests.Converters.DuplicateNameEnum' contains two members 'foo_bar' 'and 'FooBar' with the same name 'foo_bar'. Multiple members with the same name in one type are not supported. Consider changing one of the member names using EnumMemberAttribute attribute.");
}
[Test]
public void EnumMemberWithNumbers()
{
StringEnumConverter converter = new StringEnumConverter();
NumberNamesEnum e = JsonConvert.DeserializeObject<NumberNamesEnum>("\"1\"", converter);
Assert.AreEqual(NumberNamesEnum.second, e);
e = JsonConvert.DeserializeObject<NumberNamesEnum>("\"2\"", converter);
Assert.AreEqual(NumberNamesEnum.first, e);
e = JsonConvert.DeserializeObject<NumberNamesEnum>("\"3\"", converter);
Assert.AreEqual(NumberNamesEnum.third, e);
}
[Test]
public void EnumMemberWithNumbers_NoIntegerValues()
{
StringEnumConverter converter = new StringEnumConverter { AllowIntegerValues = false };
NumberNamesEnum e = JsonConvert.DeserializeObject<NumberNamesEnum>("\"1\"", converter);
Assert.AreEqual(NumberNamesEnum.second, e);
e = JsonConvert.DeserializeObject<NumberNamesEnum>("\"2\"", converter);
Assert.AreEqual(NumberNamesEnum.first, e);
e = JsonConvert.DeserializeObject<NumberNamesEnum>("\"3\"", converter);
Assert.AreEqual(NumberNamesEnum.third, e);
}
#endif
[Test]
public void AllowIntegerValueAndStringNumber()
{
JsonSerializationException ex = ExceptionAssert.Throws<JsonSerializationException>(() =>
{
JsonConvert.DeserializeObject<StoreColor>("\"1\"", new StringEnumConverter {AllowIntegerValues = false});
});
Assert.AreEqual("Integer string '1' is not allowed.", ex.InnerException.Message);
}
}
#if !NET20
@@ -587,6 +634,17 @@ namespace Newtonsoft.Json.Tests.Converters
public DuplicateNameEnum2 Value2 { get; set; }
}
[DataContract]
public enum NumberNamesEnum
{
[EnumMember(Value = "2")]
first,
[EnumMember(Value = "1")]
second,
[EnumMember(Value = "3")]
third
}
[DataContract]
public enum DuplicateNameEnum
{
@@ -1,4 +1,5 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
@@ -21,6 +22,7 @@
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
@@ -134,7 +136,8 @@ namespace Newtonsoft.Json.Converters
if (reader.TokenType == JsonToken.String)
{
string enumText = reader.Value.ToString();
return EnumUtils.ParseEnumName(enumText, isNullable, t);
return EnumUtils.ParseEnumName(enumText, isNullable, !AllowIntegerValues, t);
}
if (reader.TokenType == JsonToken.Integer)
+19 -1
View File
@@ -190,7 +190,7 @@ namespace Newtonsoft.Json.Utilities
return values;
}
public static object ParseEnumName(string enumText, bool isNullable, Type t)
public static object ParseEnumName(string enumText, bool isNullable, bool disallowValue, Type t)
{
if (enumText == string.Empty && isNullable)
{
@@ -222,6 +222,24 @@ namespace Newtonsoft.Json.Utilities
else
{
finalEnumText = enumText;
if (disallowValue)
{
bool isNumber = true;
for (int i = 0; i < finalEnumText.Length; i++)
{
if (!char.IsNumber(finalEnumText[i]))
{
isNumber = false;
break;
}
}
if (isNumber)
{
throw new FormatException("Integer string '{0}' is not allowed.".FormatWith(CultureInfo.InvariantCulture, enumText));
}
}
}
return Enum.Parse(t, finalEnumText, true);