diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index 4e52ea21..da130734 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -864,6 +864,29 @@ namespace Newtonsoft.Json.Tests.Serialization Assert.AreEqual(input.Result, deserialized.Result); } + [Test] + public void DeserializeVersionString() + { + string json = "['1.2.3.4']"; + List deserialized = JsonConvert.DeserializeObject>(json); + + Assert.AreEqual(1, deserialized[0].Major); + Assert.AreEqual(2, deserialized[0].Minor); + Assert.AreEqual(3, deserialized[0].Build); + Assert.AreEqual(4, deserialized[0].Revision); + } + + [Test] + public void DeserializeVersionString_Fail() + { + string json = "['1.2.3.4444444444444444444444']"; + + ExceptionAssert.Throws(() => + { + JsonConvert.DeserializeObject>(json); + }, @"Error converting value ""1.2.3.4444444444444444444444"" to type 'System.Version'. Path '[0]', line 1, position 31."); + } + [Test] public void DeserializeJObjectWithComments() { diff --git a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs index d9353a77..4ff2fa59 100644 --- a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs @@ -454,31 +454,43 @@ namespace Newtonsoft.Json.Utilities return ConvertResult.Success; } - if (initialValue is string) + string s = initialValue as string; + if (s != null) { if (targetType == typeof(Guid)) { - value = new Guid((string)initialValue); + value = new Guid(s); return ConvertResult.Success; } if (targetType == typeof(Uri)) { - value = new Uri((string)initialValue, UriKind.RelativeOrAbsolute); + value = new Uri(s, UriKind.RelativeOrAbsolute); return ConvertResult.Success; } if (targetType == typeof(TimeSpan)) { - value = ParseTimeSpan((string)initialValue); + value = ParseTimeSpan(s); return ConvertResult.Success; } if (targetType == typeof(byte[])) { - value = System.Convert.FromBase64String((string)initialValue); + value = System.Convert.FromBase64String(s); return ConvertResult.Success; } + if (targetType == typeof(Version)) + { + Version result; + if (VersionTryParse(s, out result)) + { + value = result; + return ConvertResult.Success; + } + value = null; + return ConvertResult.NoValidConversion; + } if (typeof(Type).IsAssignableFrom(targetType)) { - value = Type.GetType((string)initialValue, true); + value = Type.GetType(s, true); return ConvertResult.Success; } } @@ -626,6 +638,25 @@ namespace Newtonsoft.Json.Utilities } #endif + public static bool VersionTryParse(string input, out Version result) + { +#if !(NET20 || NET35) + return Version.TryParse(input, out result); +#else + // improve failure performance with regex? + try + { + result = new Version(input); + return true; + } + catch + { + result = null; + return false; + } +#endif + } + public static bool IsInteger(object value) { switch (GetTypeCode(value.GetType()))