-Added a special case to correctly deserialize Version class
-Changed Silverlight and Windows Phone assemblies in NuGet to be strong named -Changed CamelCasePropertyNamesContractResolver to improve camel casing property names -Fixed QuoteChar not being used when writing DateTimes, TimeSpans, Uris and Guids
This commit is contained in:
+3
-7
@@ -19,13 +19,9 @@
|
||||
@{Name = "Newtonsoft.Json"; TestsName = "Newtonsoft.Json.Tests"; Constants=""; FinalDir="Net40"; NuGetDir = "net40"; Framework="net-4.0"; Sign=$true},
|
||||
@{Name = "Newtonsoft.Json.Portable"; TestsName = "Newtonsoft.Json.Tests.Portable"; Constants="PORTABLE"; FinalDir="Portable"; NuGetDir = "portable-net40+sl4+wp7+win8"; Framework="net-4.0"; Sign=$true},
|
||||
@{Name = "Newtonsoft.Json.WinRT"; TestsName = $null; Constants="NETFX_CORE"; FinalDir="WinRT"; NuGetDir = "winrt45"; Framework="net-4.5"; Sign=$true},
|
||||
|
||||
# unsigned SL/WP
|
||||
@{Name = "Newtonsoft.Json.WindowsPhone"; TestsName = $null; Constants="SILVERLIGHT;WINDOWS_PHONE"; FinalDir="WindowsPhone"; NuGetDir = "sl3-wp,sl4-windowsphone71"; Framework="net-4.0"; Sign=$false},
|
||||
@{Name = "Newtonsoft.Json.Silverlight"; TestsName = "Newtonsoft.Json.Tests.Silverlight"; Constants="SILVERLIGHT"; FinalDir="Silverlight"; NuGetDir = "sl4"; Framework="net-4.0"; Sign=$false},
|
||||
# signed SL/WP
|
||||
@{Name = "Newtonsoft.Json.WindowsPhone"; TestsName = $null; Constants="SILVERLIGHT;WINDOWS_PHONE"; FinalDir="WindowsPhone\Signed"; NuGetDir = $null; Framework="net-4.0"; Sign=$true},
|
||||
@{Name = "Newtonsoft.Json.Silverlight"; TestsName = "Newtonsoft.Json.Tests.Silverlight"; Constants="SILVERLIGHT"; FinalDir="Silverlight\Signed"; NuGetDir = $null; Framework="net-4.0"; Sign=$true},
|
||||
|
||||
@{Name = "Newtonsoft.Json.WindowsPhone"; TestsName = $null; Constants="SILVERLIGHT;WINDOWS_PHONE"; FinalDir="WindowsPhone"; NuGetDir = "sl3-wp,sl4-windowsphone71"; Framework="net-4.0"; Sign=$true},
|
||||
@{Name = "Newtonsoft.Json.Silverlight"; TestsName = "Newtonsoft.Json.Tests.Silverlight"; Constants="SILVERLIGHT"; FinalDir="Silverlight"; NuGetDir = "sl4"; Framework="net-4.0"; Sign=$true},
|
||||
|
||||
@{Name = "Newtonsoft.Json.Net35"; TestsName = "Newtonsoft.Json.Tests.Net35"; Constants="NET35"; FinalDir="Net35"; NuGetDir = "net35"; Framework="net-2.0"; Sign=$true},
|
||||
@{Name = "Newtonsoft.Json.Net20"; TestsName = "Newtonsoft.Json.Tests.Net20"; Constants="NET20"; FinalDir="Net20"; NuGetDir = "net20"; Framework="net-2.0"; Sign=$true}
|
||||
|
||||
@@ -50,9 +50,6 @@ Json.NET comes in different versions for the various .NET frameworks.
|
||||
|
||||
Notes:
|
||||
|
||||
The Silverlight and Windows Phone builds are not strong-named.
|
||||
Use the assemblies in the Signed sub-directories for the strong-named versions.
|
||||
|
||||
Microsoft stopped support for the Compact Framework in Visual Studio 2010.
|
||||
For a Compact Framework 3.5 build download Json.NET 3.5.
|
||||
|
||||
|
||||
@@ -113,5 +113,18 @@ namespace Newtonsoft.Json.Tests.Converters
|
||||
DeserializeVersionClass("1.2.3", "2.3.4");
|
||||
DeserializeVersionClass("1.2.3.4", "2.3.4.5");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RoundtripImplicitConverter()
|
||||
{
|
||||
var version = new Version(1, 0, 0, 0);
|
||||
string reportJSON = JsonConvert.SerializeObject(version);
|
||||
|
||||
//Test
|
||||
Version report2 = JsonConvert.DeserializeObject<Version>(reportJSON);
|
||||
string reportJSON2 = JsonConvert.SerializeObject(report2);
|
||||
|
||||
Assert.AreEqual(reportJSON, reportJSON2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -854,5 +854,43 @@ _____'propertyName': NaN
|
||||
|
||||
Assert.AreEqual("{'Blah':null}", sw.ToString());
|
||||
}
|
||||
|
||||
#if !NET20
|
||||
[Test]
|
||||
public void QuoteChar()
|
||||
{
|
||||
StringWriter sw = new StringWriter();
|
||||
JsonTextWriter writer = new JsonTextWriter(sw);
|
||||
writer.Formatting = Formatting.Indented;
|
||||
writer.QuoteChar = '\'';
|
||||
|
||||
writer.WriteStartArray();
|
||||
|
||||
writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc));
|
||||
writer.WriteValue(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero));
|
||||
|
||||
writer.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
|
||||
writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc));
|
||||
writer.WriteValue(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero));
|
||||
|
||||
writer.WriteValue(new byte[] { 1, 2, 3 });
|
||||
writer.WriteValue(TimeSpan.Zero);
|
||||
writer.WriteValue(new Uri("http://www.google.com/"));
|
||||
writer.WriteValue(Guid.Empty);
|
||||
|
||||
writer.WriteEnd();
|
||||
|
||||
Assert.AreEqual(@"[
|
||||
'2000-01-01T01:01:01Z',
|
||||
'2000-01-01T01:01:01+00:00',
|
||||
'\/Date(946688461000)\/',
|
||||
'\/Date(946688461000+0000)\/',
|
||||
'AQID',
|
||||
'00:00:00',
|
||||
'http://www.google.com/',
|
||||
'00000000-0000-0000-0000-000000000000'
|
||||
]", sw.ToString());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -274,6 +274,7 @@
|
||||
<Compile Include="TestObjects\UserNullable.cs" />
|
||||
<Compile Include="Utilities\DynamicReflectionDelegateFactoryTests.cs" />
|
||||
<Compile Include="Utilities\ReflectionUtilsTests.cs" />
|
||||
<Compile Include="Utilities\StringUtilsTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{3259AA49-8AA1-44D3-9025-A0B520596A8C}" />
|
||||
|
||||
@@ -293,6 +293,7 @@
|
||||
<Compile Include="TestObjects\UserNullable.cs" />
|
||||
<Compile Include="Utilities\DynamicReflectionDelegateFactoryTests.cs" />
|
||||
<Compile Include="Utilities\ReflectionUtilsTests.cs" />
|
||||
<Compile Include="Utilities\StringUtilsTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Newtonsoft.Json\Newtonsoft.Json.csproj">
|
||||
|
||||
@@ -76,5 +76,5 @@ using System.Security;
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("4.5.0.0")]
|
||||
#if !PocketPC
|
||||
[assembly: AssemblyFileVersion("4.5.10.15503")]
|
||||
[assembly: AssemblyFileVersion("4.5.10.15504")]
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
|
||||
namespace Newtonsoft.Json.Tests.Utilities
|
||||
{
|
||||
[TestFixture]
|
||||
public class StringUtilsTests : TestFixtureBase
|
||||
{
|
||||
[Test]
|
||||
public void ToCamelCaseTest()
|
||||
{
|
||||
Assert.AreEqual("urlValue", StringUtils.ToCamelCase("URLValue"));
|
||||
Assert.AreEqual("url", StringUtils.ToCamelCase("URL"));
|
||||
Assert.AreEqual("id", StringUtils.ToCamelCase("ID"));
|
||||
Assert.AreEqual("i", StringUtils.ToCamelCase("I"));
|
||||
Assert.AreEqual("", StringUtils.ToCamelCase(""));
|
||||
Assert.AreEqual(null, StringUtils.ToCamelCase(null));
|
||||
Assert.AreEqual("iPhone", StringUtils.ToCamelCase("iPhone"));
|
||||
Assert.AreEqual("person", StringUtils.ToCamelCase("Person"));
|
||||
Assert.AreEqual("iPhone", StringUtils.ToCamelCase("IPhone"));
|
||||
Assert.AreEqual("i Phone", StringUtils.ToCamelCase("I Phone"));
|
||||
Assert.AreEqual(" IPhone", StringUtils.ToCamelCase(" IPhone"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,7 @@ namespace Newtonsoft.Json
|
||||
|
||||
using (StringWriter writer = StringUtils.CreateStringWriter(64))
|
||||
{
|
||||
WriteDateTimeString(writer, updatedDateTime, updatedDateTime.GetUtcOffset(), updatedDateTime.Kind, format);
|
||||
WriteDateTimeString(writer, updatedDateTime, updatedDateTime.GetUtcOffset(), updatedDateTime.Kind, format, '"');
|
||||
return writer.ToString();
|
||||
}
|
||||
}
|
||||
@@ -155,27 +155,33 @@ namespace Newtonsoft.Json
|
||||
/// <param name="format">The format the date will be converted to.</param>
|
||||
/// <returns>A JSON string representation of the <see cref="DateTimeOffset"/>.</returns>
|
||||
public static string ToString(DateTimeOffset value, DateFormatHandling format)
|
||||
{
|
||||
return ToString(value, format, '"');
|
||||
}
|
||||
|
||||
internal static string ToString(DateTimeOffset value, DateFormatHandling format, char quoteChar)
|
||||
{
|
||||
using (StringWriter writer = StringUtils.CreateStringWriter(64))
|
||||
{
|
||||
WriteDateTimeString(writer, (format == DateFormatHandling.IsoDateFormat) ? value.DateTime : value.UtcDateTime, value.Offset, DateTimeKind.Local, format);
|
||||
WriteDateTimeString(writer, (format == DateFormatHandling.IsoDateFormat) ? value.DateTime : value.UtcDateTime, value.Offset, DateTimeKind.Local, format, quoteChar);
|
||||
return writer.ToString();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal static void WriteDateTimeString(TextWriter writer, DateTime value, DateFormatHandling format)
|
||||
internal static void WriteDateTimeString(TextWriter writer, DateTime value, DateFormatHandling format, char quoteChar)
|
||||
{
|
||||
WriteDateTimeString(writer, value, value.GetUtcOffset(), value.Kind, format);
|
||||
WriteDateTimeString(writer, value, value.GetUtcOffset(), value.Kind, format, quoteChar);
|
||||
}
|
||||
|
||||
internal static void WriteDateTimeString(TextWriter writer, DateTime value, TimeSpan offset, DateTimeKind kind, DateFormatHandling format)
|
||||
internal static void WriteDateTimeString(TextWriter writer, DateTime value, TimeSpan offset, DateTimeKind kind, DateFormatHandling format, char quoteChar)
|
||||
{
|
||||
if (format == DateFormatHandling.MicrosoftDateFormat)
|
||||
{
|
||||
long javaScriptTicks = ConvertDateTimeToJavaScriptTicks(value, offset);
|
||||
|
||||
writer.Write(@"""\/Date(");
|
||||
writer.Write(quoteChar);
|
||||
writer.Write(@"\/Date(");
|
||||
writer.Write(javaScriptTicks);
|
||||
|
||||
switch (kind)
|
||||
@@ -189,11 +195,12 @@ namespace Newtonsoft.Json
|
||||
break;
|
||||
}
|
||||
|
||||
writer.Write(@")\/""");
|
||||
writer.Write(@")\/");
|
||||
writer.Write(quoteChar);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(@"""");
|
||||
writer.Write(quoteChar);
|
||||
writer.Write(value.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFF", CultureInfo.InvariantCulture));
|
||||
|
||||
switch (kind)
|
||||
@@ -207,7 +214,7 @@ namespace Newtonsoft.Json
|
||||
}
|
||||
|
||||
|
||||
writer.Write(@"""");
|
||||
writer.Write(quoteChar);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,6 +492,11 @@ namespace Newtonsoft.Json
|
||||
/// <param name="value">The value to convert.</param>
|
||||
/// <returns>A JSON string representation of the <see cref="Guid"/>.</returns>
|
||||
public static string ToString(Guid value)
|
||||
{
|
||||
return ToString(value, '"');
|
||||
}
|
||||
|
||||
internal static string ToString(Guid value, char quoteChar)
|
||||
{
|
||||
string text = null;
|
||||
|
||||
@@ -494,7 +506,7 @@ namespace Newtonsoft.Json
|
||||
text = value.ToString("D");
|
||||
#endif
|
||||
|
||||
return '"' + text + '"';
|
||||
return quoteChar + text + quoteChar;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -504,7 +516,12 @@ namespace Newtonsoft.Json
|
||||
/// <returns>A JSON string representation of the <see cref="TimeSpan"/>.</returns>
|
||||
public static string ToString(TimeSpan value)
|
||||
{
|
||||
return '"' + value.ToString() + '"';
|
||||
return ToString(value, '"');
|
||||
}
|
||||
|
||||
internal static string ToString(TimeSpan value, char quoteChar)
|
||||
{
|
||||
return ToString(value.ToString(), quoteChar);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -517,7 +534,12 @@ namespace Newtonsoft.Json
|
||||
if (value == null)
|
||||
return Null;
|
||||
|
||||
return ToString(value.ToString());
|
||||
return ToString(value, '"');
|
||||
}
|
||||
|
||||
internal static string ToString(Uri value, char quoteChar)
|
||||
{
|
||||
return ToString(value.ToString(), quoteChar);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -439,7 +439,7 @@ namespace Newtonsoft.Json
|
||||
{
|
||||
InternalWriteValue(JsonToken.Date);
|
||||
value = JsonConvert.EnsureDateTime(value, DateTimeZoneHandling);
|
||||
JsonConvert.WriteDateTimeString(_writer, value, DateFormatHandling);
|
||||
JsonConvert.WriteDateTimeString(_writer, value, DateFormatHandling, _quoteChar);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -470,7 +470,7 @@ namespace Newtonsoft.Json
|
||||
public override void WriteValue(DateTimeOffset value)
|
||||
{
|
||||
InternalWriteValue(JsonToken.Date);
|
||||
WriteValueInternal(JsonConvert.ToString(value, DateFormatHandling), JsonToken.Date);
|
||||
WriteValueInternal(JsonConvert.ToString(value, DateFormatHandling, _quoteChar), JsonToken.Date);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -481,7 +481,7 @@ namespace Newtonsoft.Json
|
||||
public override void WriteValue(Guid value)
|
||||
{
|
||||
InternalWriteValue(JsonToken.String);
|
||||
WriteValueInternal(JsonConvert.ToString(value), JsonToken.String);
|
||||
WriteValueInternal(JsonConvert.ToString(value, _quoteChar), JsonToken.String);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -491,7 +491,7 @@ namespace Newtonsoft.Json
|
||||
public override void WriteValue(TimeSpan value)
|
||||
{
|
||||
InternalWriteValue(JsonToken.String);
|
||||
WriteValueInternal(JsonConvert.ToString(value), JsonToken.String);
|
||||
WriteValueInternal(JsonConvert.ToString(value, _quoteChar), JsonToken.String);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -507,7 +507,7 @@ namespace Newtonsoft.Json
|
||||
else
|
||||
{
|
||||
InternalWriteValue(JsonToken.String);
|
||||
WriteValueInternal(JsonConvert.ToString(value), JsonToken.String);
|
||||
WriteValueInternal(JsonConvert.ToString(value, _quoteChar), JsonToken.String);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -90,7 +90,7 @@ using System.Security;
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("4.5.0.0")]
|
||||
#if !PocketPC
|
||||
[assembly: AssemblyFileVersion("4.5.10.15503")]
|
||||
[assembly: AssemblyFileVersion("4.5.10.15504")]
|
||||
#endif
|
||||
|
||||
[assembly: CLSCompliant(true)]
|
||||
|
||||
@@ -365,15 +365,13 @@ namespace Newtonsoft.Json.Serialization
|
||||
if (attribute != null)
|
||||
contract.ItemRequired = attribute._itemRequired;
|
||||
|
||||
ConstructorInfo overrideConstructor = GetAttributeConstructor(contract.NonNullableUnderlyingType);
|
||||
|
||||
// check if a JsonConstructorAttribute has been defined and use that
|
||||
if (contract.NonNullableUnderlyingType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Any(c => c.IsDefined(typeof(JsonConstructorAttribute), true)))
|
||||
if (overrideConstructor != null)
|
||||
{
|
||||
ConstructorInfo constructor = GetAttributeConstructor(contract.NonNullableUnderlyingType);
|
||||
if (constructor != null)
|
||||
{
|
||||
contract.OverrideConstructor = constructor;
|
||||
contract.ConstructorParameters.AddRange(CreateConstructorParameters(constructor, contract.Properties));
|
||||
}
|
||||
contract.OverrideConstructor = overrideConstructor;
|
||||
contract.ConstructorParameters.AddRange(CreateConstructorParameters(overrideConstructor, contract.Properties));
|
||||
}
|
||||
else if (contract.MemberSerialization == MemberSerialization.Fields)
|
||||
{
|
||||
@@ -405,6 +403,10 @@ namespace Newtonsoft.Json.Serialization
|
||||
else if (markedConstructors.Count == 1)
|
||||
return markedConstructors[0];
|
||||
|
||||
// little hack to get Version objects to deserialize correctly
|
||||
if (objectType == typeof(Version))
|
||||
return objectType.GetConstructor(new [] { typeof(int), typeof(int), typeof(int), typeof(int) });
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -155,17 +155,23 @@ namespace Newtonsoft.Json.Utilities
|
||||
if (!char.IsUpper(s[0]))
|
||||
return s;
|
||||
|
||||
string camelCase = null;
|
||||
#if !(NETFX_CORE || PORTABLE)
|
||||
camelCase = char.ToLower(s[0], CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture);
|
||||
#else
|
||||
camelCase = char.ToLower(s[0]).ToString();
|
||||
#endif
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
{
|
||||
bool hasNext = (i + 1 < s.Length);
|
||||
if ((i == 0 || !hasNext) || char.IsUpper(s[i + 1]))
|
||||
{
|
||||
char lowerCase = char.ToLower(s[i], CultureInfo.InvariantCulture);
|
||||
sb.Append(lowerCase);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(s.Substring(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (s.Length > 1)
|
||||
camelCase += s.Substring(1);
|
||||
|
||||
return camelCase;
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static bool IsHighSurrogate(char c)
|
||||
|
||||
Reference in New Issue
Block a user