diff --git a/Build/Newtonsoft.Json.nuspec b/Build/Newtonsoft.Json.nuspec
index 27eedf05..0b1eadb9 100644
--- a/Build/Newtonsoft.Json.nuspec
+++ b/Build/Newtonsoft.Json.nuspec
@@ -1,15 +1,47 @@
-
- Newtonsoft.Json
-
- Json.NET
- Json.NET is a popular high-performance JSON framework for .NET
- James Newton-King
- en-US
- http://www.newtonsoft.com/json
- http://www.newtonsoft.com/content/images/nugeticon.png
- https://raw.github.com/JamesNK/Newtonsoft.Json/master/LICENSE.md
- json
-
+
+ Newtonsoft.Json
+
+ Json.NET
+ Json.NET is a popular high-performance JSON framework for .NET
+ James Newton-King
+ en-US
+ http://www.newtonsoft.com/json
+ http://www.newtonsoft.com/content/images/nugeticon.png
+ https://raw.github.com/JamesNK/Newtonsoft.Json/master/LICENSE.md
+ json
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Build/build.ps1 b/Build/build.ps1
index 7e6e6e86..da167a49 100644
--- a/Build/build.ps1
+++ b/Build/build.ps1
@@ -1,8 +1,8 @@
properties {
- $zipFileName = "Json80r3.zip"
+ $zipFileName = "Json80r4.zip"
$majorVersion = "8.0"
- $majorWithReleaseVersion = "8.0.3"
- $nugetPrelease = $null
+ $majorWithReleaseVersion = "8.0.4"
+ $nugetPrerelease = "beta1"
$version = GetVersion $majorWithReleaseVersion
$packageId = "Newtonsoft.Json"
$signAssemblies = $false
@@ -11,7 +11,7 @@
$buildNuGet = $true
$treatWarningsAsErrors = $false
$workingName = if ($workingName) {$workingName} else {"Working"}
- $dnvmVersion = "1.0.0-rc1-update1"
+ $netCliVersion = "1.0.0-preview1-002702"
$baseDir = resolve-path ..
$buildDir = "$baseDir\Build"
@@ -22,9 +22,9 @@
$workingDir = "$baseDir\$workingName"
$workingSourceDir = "$workingDir\Src"
$builds = @(
- @{Name = "Newtonsoft.Json.Dotnet"; TestsName = "Newtonsoft.Json.Tests.Dotnet"; BuildFunction = "DnxBuild"; TestsFunction = "DnxTests"; Constants="dotnet"; FinalDir=$null; NuGetDir = $null; Framework=$null},
+ @{Name = "Newtonsoft.Json.Dotnet"; TestsName = "Newtonsoft.Json.Tests.Dotnet"; BuildFunction = "NetCliBuild"; TestsFunction = "NetCliTests"; Constants="dotnet"; FinalDir="netstandard1.0"; NuGetDir = "netstandard1.0"; Framework=$null},
@{Name = "Newtonsoft.Json"; TestsName = "Newtonsoft.Json.Tests"; BuildFunction = "MSBuildBuild"; TestsFunction = "NUnitTests"; Constants=""; FinalDir="Net45"; NuGetDir = "net45"; Framework="net-4.0"},
- @{Name = "Newtonsoft.Json.Portable"; TestsName = "Newtonsoft.Json.Tests.Portable"; BuildFunction = "MSBuildBuild"; TestsFunction = "NUnitTests"; Constants="PORTABLE"; FinalDir="Portable"; NuGetDir = "portable-net45+wp80+win8+wpa81+dnxcore50"; Framework="net-4.0"},
+ @{Name = "Newtonsoft.Json.Portable"; TestsName = "Newtonsoft.Json.Tests.Portable"; BuildFunction = "MSBuildBuild"; TestsFunction = "NUnitTests"; Constants="PORTABLE"; FinalDir="Portable"; NuGetDir = "portable-net45+wp80+win8+wpa81"; Framework="net-4.0"},
@{Name = "Newtonsoft.Json.Portable40"; TestsName = "Newtonsoft.Json.Tests.Portable40"; BuildFunction = "MSBuildBuild"; TestsFunction = "NUnitTests"; Constants="PORTABLE40"; FinalDir="Portable40"; NuGetDir = "portable-net40+sl5+wp80+win8+wpa81"; Framework="net-4.0"},
@{Name = "Newtonsoft.Json.Net40"; TestsName = "Newtonsoft.Json.Tests.Net40"; BuildFunction = "MSBuildBuild"; TestsFunction = "NUnitTests"; Constants="NET40"; FinalDir="Net40"; NuGetDir = "net40"; Framework="net-4.0"},
@{Name = "Newtonsoft.Json.Net35"; TestsName = "Newtonsoft.Json.Tests.Net35"; BuildFunction = "MSBuildBuild"; TestsFunction = "NUnitTests"; Constants="NET35"; FinalDir="Net35"; NuGetDir = "net35"; Framework="net-2.0"},
@@ -90,11 +90,7 @@ task Package -depends Build {
if ($buildNuGet)
{
- $nugetVersion = $majorWithReleaseVersion
- if ($nugetPrelease -ne $null)
- {
- $nugetVersion = $nugetVersion + "-" + $nugetPrelease
- }
+ $nugetVersion = GetNuGetVersion
New-Item -Path $workingDir\NuGet -ItemType Directory
@@ -136,6 +132,7 @@ task Package -depends Build {
Write-Host
exec { .\Tools\NuGet\NuGet.exe pack $nuspecPath -Symbols }
+ exec { dotnet pack $workingSourceDir\Newtonsoft.Json\project.json -c Release }
move -Path .\*.nupkg -Destination $workingDir\NuGet
}
@@ -204,36 +201,32 @@ function MSBuildBuild($build)
exec { msbuild "/t:Clean;Rebuild" /p:Configuration=Release "/p:CopyNuGetImplementations=true" "/p:Platform=Any CPU" "/p:PlatformTarget=AnyCPU" /p:OutputPath=bin\Release\$finalDir\ /p:AssemblyOriginatorKeyFile=$signKeyPath "/p:SignAssembly=$signAssemblies" "/p:TreatWarningsAsErrors=$treatWarningsAsErrors" "/p:VisualStudioVersion=14.0" /p:DefineConstants=`"$constants`" "$workingSourceDir\$name.sln" | Out-Default } "Error building $name"
}
-function DnxBuild($build)
+function NetCliBuild($build)
{
$name = $build.Name
$projectPath = "$workingSourceDir\Newtonsoft.Json\project.json"
- exec { dnvm install $dnvmVersion -r clr | Out-Default }
- exec { dnvm use $dnvmVersion -r clr | Out-Default }
+ exec { .\Tools\Dotnet\install.ps1 -Version $netCliVersion | Out-Default }
+ exec { dotnet --version | Out-Default }
Write-Host -ForegroundColor Green "Restoring packages for $name"
Write-Host
- exec { dnu restore $projectPath | Out-Default }
+ exec { dotnet restore $projectPath | Out-Default }
Write-Host -ForegroundColor Green "Building $projectPath"
- exec { dnu build $projectPath --configuration Release | Out-Default }
+ exec { dotnet build $projectPath -f netstandard1.0 -c Release -o bin\Release\netstandard1.0 | Out-Default }
}
-function DnxTests($build)
+function NetCliTests($build)
{
$name = $build.TestsName
- #Write-Host -ForegroundColor Green "Ensuring latest CoreCLR is installed for $name"
- #Write-Host
- #exec { & $toolsDir\Kvm\kvm.ps1 upgrade -r CoreCLR -NoNative | Out-Default }
-
- exec { dnvm install $dnvmVersion -r coreclr | Out-Default }
- exec { dnvm use $dnvmVersion -r coreclr | Out-Default }
+ exec { .\Tools\Dotnet\install.ps1 -Version $netCliVersion | Out-Default }
+ exec { dotnet --version | Out-Default }
Write-Host -ForegroundColor Green "Restoring packages for $name"
Write-Host
- exec { dnu restore "$workingSourceDir\Newtonsoft.Json.Tests\project.json" | Out-Default }
+ exec { dotnet restore "$workingSourceDir\Newtonsoft.Json.Tests\project.json" | Out-Default }
Write-Host -ForegroundColor Green "Ensuring test project builds for $name"
Write-Host
@@ -241,7 +234,7 @@ function DnxTests($build)
try
{
Set-Location "$workingSourceDir\Newtonsoft.Json.Tests"
- exec { dnx --configuration Release test | Out-Default }
+ exec { dotnet test "$workingSourceDir\Newtonsoft.Json.Tests\project.json" -f netcoreapp1.0 -c Release -parallel none | Out-Default }
}
finally
{
@@ -266,6 +259,17 @@ function NUnitTests($build)
exec { .\Tools\NUnit\nunit-console.exe "$workingDir\Deployed\Bin\$finalDir\Newtonsoft.Json.Tests.dll" /framework=$framework /xml:$workingDir\$name.xml | Out-Default } "Error running $name tests"
}
+function GetNuGetVersion()
+{
+ $nugetVersion = $majorWithReleaseVersion
+ if ($nugetPrerelease -ne $null)
+ {
+ $nugetVersion = $nugetVersion + "-" + $nugetPrerelease
+ }
+
+ return $nugetVersion
+}
+
function GetConstants($constants, $includeSigned)
{
$signed = switch($includeSigned) { $true { ";SIGNED" } default { "" } }
@@ -345,8 +349,10 @@ function Update-Project {
$file = switch($sign) { $true { $signKeyPath } default { $null } }
$json = (Get-Content $projectPath) -join "`n" | ConvertFrom-Json
- $options = @{"warningsAsErrors" = $true; "keyFile" = $file; "define" = ((GetConstants "dotnet" $sign) -split ";") }
- Add-Member -InputObject $json -MemberType NoteProperty -Name "compilationOptions" -Value $options -Force
+ $options = @{"warningsAsErrors" = $true; "xmlDoc" = $true; "keyFile" = $file; "define" = ((GetConstants "dotnet" $sign) -split ";") }
+ Add-Member -InputObject $json -MemberType NoteProperty -Name "buildOptions" -Value $options -Force
+
+ $json.version = GetNuGetVersion
ConvertTo-Json $json -Depth 10 | Set-Content $projectPath
}
diff --git a/Build/runbuild.cmd b/Build/runbuild.cmd
index e6dc8e57..18b460cd 100644
--- a/Build/runbuild.cmd
+++ b/Build/runbuild.cmd
@@ -1,5 +1,5 @@
cls
-powershell -Command "& { [Console]::WindowWidth = 150; [Console]::WindowHeight = 50; Start-Transcript %~dp0runbuild.txt; Import-Module %~dp0..\Tools\PSake\psake.psm1; Invoke-psake %~dp0..\Build\build.ps1 %*; Stop-Transcript; exit !($psake.build_success); }"
+powershell -Command "& { [Console]::WindowWidth = 150; [Console]::WindowHeight = 50; Start-Transcript '%~dp0runbuild.txt'; Import-Module '%~dp0..\Tools\PSake\psake.psm1'; Invoke-psake '%~dp0..\Build\build.ps1' %*; Stop-Transcript; exit !($psake.build_success); }"
ECHO %ERRORLEVEL%
EXIT /B %ERRORLEVEL%
\ No newline at end of file
diff --git a/Doc/JsonNetVsDotNetSerializers.aml b/Doc/JsonNetVsDotNetSerializers.aml
index 4edc82c2..9beff0d9 100644
--- a/Doc/JsonNetVsDotNetSerializers.aml
+++ b/Doc/JsonNetVsDotNetSerializers.aml
@@ -431,7 +431,7 @@
- Serailizes Entity Framework
+ Serializes Entity Framework
@@ -499,4 +499,4 @@
-
\ No newline at end of file
+
diff --git a/Src/Newtonsoft.Json.TestConsole/Program.cs b/Src/Newtonsoft.Json.TestConsole/Program.cs
index 051a5e65..9df1c254 100644
--- a/Src/Newtonsoft.Json.TestConsole/Program.cs
+++ b/Src/Newtonsoft.Json.TestConsole/Program.cs
@@ -31,6 +31,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
+using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Tests;
using Newtonsoft.Json.Tests.Converters;
@@ -52,6 +53,7 @@ namespace Newtonsoft.Json.TestConsole
//t.DeserializeLargeJson();
//PerformanceTests t = new PerformanceTests();
+ LargeArrayJTokenPathPerformance();
//t.Iterations = 50000;
//t.BenchmarkDeserializeMethod(PerformanceTests.SerializeMethod.JsonNet, PerformanceTests.JsonText);
@@ -62,7 +64,7 @@ namespace Newtonsoft.Json.TestConsole
//ReadLargeJson();
//WriteLargeJson();
- DeserializeJson();
+ //DeserializeJson();
//ReadLargeJson();
//ReadLargeJsonJavaScriptSerializer();
@@ -72,6 +74,28 @@ namespace Newtonsoft.Json.TestConsole
Console.ReadKey();
}
+ public static void LargeArrayJTokenPathPerformance()
+ {
+ JArray a = new JArray();
+ for (int i = 0; i < 100000; i++)
+ {
+ a.Add(i);
+ }
+
+ JToken last = a.Last;
+
+ int interations = 1000;
+
+ Console.WriteLine("Ready!!!");
+ Console.ReadKey();
+
+ string p = null;
+ for (int i = 0; i < interations; i++)
+ {
+ p = last.Path;
+ }
+ }
+
public static void DeserializeJson()
{
PerformanceTests t = new PerformanceTests();
diff --git a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs
index 4c1c2c7b..8684df2c 100644
--- a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs
@@ -130,6 +130,36 @@ namespace Newtonsoft.Json.Tests.Converters
}
#if !NET20
+ [Test]
+ public void SerializeDollarProperty()
+ {
+ string json1 = @"{""$"":""test""}";
+
+ var doc = JsonConvert.DeserializeXNode(json1);
+
+ Assert.AreEqual(@"<_x0024_>test", doc.ToString());
+
+ var json2 = JsonConvert.SerializeXNode(doc);
+
+ Assert.AreEqual(json1, json2);
+ }
+
+ [Test]
+ public void SerializeNonKnownDollarProperty()
+ {
+ string json1 = @"{""$JELLY"":""test""}";
+
+ var doc = JsonConvert.DeserializeXNode(json1);
+
+ Console.WriteLine(doc.ToString());
+
+ Assert.AreEqual(@"<_x0024_JELLY>test", doc.ToString());
+
+ var json2 = JsonConvert.SerializeXNode(doc);
+
+ Assert.AreEqual(json1, json2);
+ }
+
public class MyModel
{
public string MyProperty { get; set; }
@@ -2670,6 +2700,58 @@ namespace Newtonsoft.Json.Tests.Converters
Assert.AreEqual("null", json);
}
+
+ [Test]
+ public void SerializeElementExplicitAttributeNamespace()
+ {
+ var original = XElement.Parse("");
+ Assert.AreEqual(@"", original.ToString());
+
+ var json = JsonConvert.SerializeObject(original);
+ Assert.AreEqual(@"{""MyElement"":{""@xmlns"":""http://example.com""}}", json);
+
+ var deserialized = JsonConvert.DeserializeObject(json);
+ Assert.AreEqual(@"", deserialized.ToString());
+ }
+
+ [Test]
+ public void SerializeElementImplicitAttributeNamespace()
+ {
+ var original = new XElement("{http://example.com}MyElement");
+ Assert.AreEqual(@"", original.ToString());
+
+ var json = JsonConvert.SerializeObject(original);
+ Assert.AreEqual(@"{""MyElement"":{""@xmlns"":""http://example.com""}}", json);
+
+ var deserialized = JsonConvert.DeserializeObject(json);
+ Assert.AreEqual(@"", deserialized.ToString());
+ }
+
+ [Test]
+ public void SerializeDocumentExplicitAttributeNamespace()
+ {
+ var original = XDocument.Parse("");
+ Assert.AreEqual(@"", original.ToString());
+
+ var json = JsonConvert.SerializeObject(original);
+ Assert.AreEqual(@"{""MyElement"":{""@xmlns"":""http://example.com""}}", json);
+
+ var deserialized = JsonConvert.DeserializeObject(json);
+ Assert.AreEqual(@"", deserialized.ToString());
+ }
+
+ [Test]
+ public void SerializeDocumentImplicitAttributeNamespace()
+ {
+ var original = new XDocument(new XElement("{http://example.com}MyElement"));
+ Assert.AreEqual(@"", original.ToString());
+
+ var json = JsonConvert.SerializeObject(original);
+ Assert.AreEqual(@"{""MyElement"":{""@xmlns"":""http://example.com""}}", json);
+
+ var deserialized = JsonConvert.DeserializeObject(json);
+ Assert.AreEqual(@"", deserialized.ToString());
+ }
#endif
}
}
diff --git a/Src/Newtonsoft.Json.Tests/Documentation/ConvertingJsonAndXmlTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/ConvertingJsonAndXmlTests.cs
index f3cd803f..c43a4c05 100644
--- a/Src/Newtonsoft.Json.Tests/Documentation/ConvertingJsonAndXmlTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Documentation/ConvertingJsonAndXmlTests.cs
@@ -54,20 +54,22 @@ using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
namespace Newtonsoft.Json.Tests.Documentation
{
- public class ConvertingJsonAndXmlTests
+ [TestFixture]
+ public class ConvertingJsonAndXmlTests : TestFixtureBase
{
+ [Test]
public void SerializeXmlNode()
{
#region SerializeXmlNode
string xml = @"
- Alan
- http://www.google.com
+ Alan
+ http://www.google.com
- Louis
- http://www.yahoo.com
+ Louis
+ http://www.yahoo.com
";
@@ -98,6 +100,7 @@ namespace Newtonsoft.Json.Tests.Documentation
#endregion
}
+ [Test]
public void DeserializeXmlNode()
{
#region DeserializeXmlNode
@@ -126,17 +129,18 @@ namespace Newtonsoft.Json.Tests.Documentation
//
//
//
- // Alan
- // http://www.google.com
+ // Alan
+ // http://www.google.com
//
//
- // Louis
- // http://www.yahoo.com
+ // Louis
+ // http://www.yahoo.com
//
//
#endregion
}
+ [Test]
public void ForceJsonArray()
{
#region ForceJsonArray
diff --git a/Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs
index 6ee92436..6ae04a70 100644
--- a/Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs
@@ -58,7 +58,7 @@ namespace Newtonsoft.Json.Tests.Documentation
{
public static StreamReader OpenText(string path)
{
- return null;
+ return new StreamReader(new MemoryStream(Encoding.UTF8.GetBytes("{}")));
}
public static StreamWriter CreateText(string path)
@@ -76,7 +76,8 @@ namespace Newtonsoft.Json.Tests.Documentation
}
}
- public class LinqToJsonTests
+ [TestFixture]
+ public class LinqToJsonTests : TestFixtureBase
{
public void LinqToJsonBasic()
{
@@ -129,9 +130,10 @@ namespace Newtonsoft.Json.Tests.Documentation
private List GetPosts()
{
- return null;
+ return new List();
}
+ [Test]
public void LinqToJsonCreateDeclaratively()
{
#region LinqToJsonCreateDeclaratively
@@ -163,7 +165,7 @@ namespace Newtonsoft.Json.Tests.Documentation
// "channel": {
// "title": "James Newton-King",
// "link": "http://james.newtonking.com",
- // "description": "James Newton-King's blog.",
+ // "description": "James Newton-King\'s blog.",
// "item": [
// {
// "title": "Json.NET 1.3 + New license + Now on CodePlex",
@@ -189,9 +191,10 @@ namespace Newtonsoft.Json.Tests.Documentation
#endregion
}
+ [Test]
public void LinqToJsonCreateFromObject()
{
- List posts = null;
+ List posts = GetPosts();
#region LinqToJsonCreateFromObject
JObject o = JObject.FromObject(new
@@ -216,6 +219,7 @@ namespace Newtonsoft.Json.Tests.Documentation
#endregion
}
+ [Test]
public void LinqToJsonCreateParse()
{
#region LinqToJsonCreateParse
@@ -231,6 +235,7 @@ namespace Newtonsoft.Json.Tests.Documentation
#endregion
}
+ [Test]
public void LinqToJsonCreateParseArray()
{
#region LinqToJsonCreateParseArray
@@ -244,6 +249,7 @@ namespace Newtonsoft.Json.Tests.Documentation
#endregion
}
+ [Test]
public void LinqToJsonReadObject()
{
#region LinqToJsonReadObject
@@ -255,6 +261,7 @@ namespace Newtonsoft.Json.Tests.Documentation
#endregion
}
+ [Test]
public void LinqToJsonSimpleQuerying()
{
#region LinqToJsonSimpleQuerying
@@ -262,7 +269,7 @@ namespace Newtonsoft.Json.Tests.Documentation
'channel': {
'title': 'James Newton-King',
'link': 'http://james.newtonking.com',
- 'description': 'James Newton-King's blog.',
+ 'description': 'James Newton-King\'s blog.',
'item': [
{
'title': 'Json.NET 1.3 + New license + Now on CodePlex',
@@ -303,9 +310,36 @@ namespace Newtonsoft.Json.Tests.Documentation
#endregion
}
+ [Test]
public void LinqToJsonQuerying()
{
- JObject rss = new JObject();
+ JObject rss = JObject.Parse(@"{
+ 'channel': {
+ 'title': 'James Newton-King',
+ 'link': 'http://james.newtonking.com',
+ 'description': 'James Newton-King\'s blog.',
+ 'item': [
+ {
+ 'title': 'Json.NET 1.3 + New license + Now on CodePlex',
+ 'description': 'Annoucing the release of Json.NET 1.3, the MIT license and the source on CodePlex',
+ 'link': 'http://james.newtonking.com/projects/json-net.aspx',
+ 'categories': [
+ 'Json.NET',
+ 'CodePlex'
+ ]
+ },
+ {
+ 'title': 'LINQ to JSON beta',
+ 'description': 'Annoucing LINQ to JSON',
+ 'link': 'http://james.newtonking.com/projects/json-net.aspx',
+ 'categories': [
+ 'Json.NET',
+ 'LINQ'
+ ]
+ }
+ ]
+ }
+ }");
#region LinqToJsonQuerying
var postTitles =
@@ -321,7 +355,7 @@ namespace Newtonsoft.Json.Tests.Documentation
//Json.NET 1.3 + New license + Now on CodePlex
var categories =
- from c in rss["channel"]["item"].Children()["category"].Values()
+ from c in rss["channel"]["item"].SelectMany(i => i["categories"]).Values()
group c by c
into g
orderby g.Count() descending
@@ -336,6 +370,9 @@ namespace Newtonsoft.Json.Tests.Documentation
//LINQ - Count: 1
//CodePlex - Count: 1
#endregion
+
+ Assert.AreEqual(2, postTitles.Count());
+ Assert.AreEqual(3, categories.Count());
}
#region LinqToJsonDeserializeObject
@@ -354,6 +391,7 @@ namespace Newtonsoft.Json.Tests.Documentation
}
#endregion
+ [Test]
public void LinqToJsonDeserializeExample()
{
#region LinqToJsonDeserializeExample
@@ -362,9 +400,10 @@ namespace Newtonsoft.Json.Tests.Documentation
'original': 'http://www.foo.com/',
'short': 'krehqk',
'error': {
- 'code':0,
- 'msg':'No action taken'
+ 'code': 0,
+ 'msg': 'No action taken'
}
+ }
}";
JObject json = JObject.Parse(jsonText);
@@ -386,17 +425,53 @@ namespace Newtonsoft.Json.Tests.Documentation
Console.WriteLine(shortie.Error.ErrorMessage);
// No action taken
#endregion
+
+ Assert.AreEqual("http://www.foo.com/", shortie.Original);
+ Assert.AreEqual("No action taken", shortie.Error.ErrorMessage);
}
+ [Test]
public void SelectTokenSimple()
{
- JObject o = new JObject();
+ JObject o = JObject.Parse(@"{
+ 'Stores': [
+ 'Lambton Quay',
+ 'Willis Street'
+ ],
+ 'Manufacturers': [
+ {
+ 'Name': 'Acme Co',
+ 'Products': [
+ {
+ 'Name': 'Anvil',
+ 'Price': 50
+ }
+ ]
+ },
+ {
+ 'Name': 'Contoso',
+ 'Products': [
+ {
+ 'Name': 'Elbow Grease',
+ 'Price': 99.95
+ },
+ {
+ 'Name': 'Headlight Fluid',
+ 'Price': 4
+ }
+ ]
+ }
+ ]
+ }");
#region SelectTokenSimple
string name = (string)o.SelectToken("Manufacturers[0].Name");
#endregion
+
+ Assert.AreEqual("Acme Co", name);
}
+ [Test]
public void SelectTokenComplex()
{
#region SelectTokenComplex
@@ -440,11 +515,45 @@ namespace Newtonsoft.Json.Tests.Documentation
string productName = (string)o.SelectToken("Manufacturers[1].Products[0].Name");
// Elbow Grease
#endregion
+
+ Assert.AreEqual("Acme Co", name);
+ Assert.AreEqual(50m, productPrice);
+ Assert.AreEqual("Elbow Grease", productName);
}
+ [Test]
public void SelectTokenLinq()
{
- JObject o = new JObject();
+ JObject o = JObject.Parse(@"{
+ 'Stores': [
+ 'Lambton Quay',
+ 'Willis Street'
+ ],
+ 'Manufacturers': [
+ {
+ 'Name': 'Acme Co',
+ 'Products': [
+ {
+ 'Name': 'Anvil',
+ 'Price': 50
+ }
+ ]
+ },
+ {
+ 'Name': 'Contoso',
+ 'Products': [
+ {
+ 'Name': 'Elbow Grease',
+ 'Price': 99.95
+ },
+ {
+ 'Name': 'Headlight Fluid',
+ 'Price': 4
+ }
+ ]
+ }
+ ]
+ }");
#region SelectTokenLinq
IList storeNames = o.SelectToken("Stores").Select(s => (string)s).ToList();
@@ -458,6 +567,10 @@ namespace Newtonsoft.Json.Tests.Documentation
decimal totalPrice = o["Manufacturers"].Sum(m => (decimal)m.SelectToken("Products[0].Price"));
// 149.95
#endregion
+
+ Assert.AreEqual(2, storeNames.Count);
+ Assert.AreEqual(2, firstProductNames.Count);
+ Assert.AreEqual(149.95m, totalPrice);
}
}
}
diff --git a/Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs
index de53557f..8861d22d 100644
--- a/Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs
@@ -53,8 +53,10 @@ using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
namespace Newtonsoft.Json.Tests.Documentation
{
- public class SerializationTests
+ [TestFixture]
+ public class SerializationTests : TestFixtureBase
{
+ [Test]
public void SerializeObject()
{
#region SerializeObject
@@ -79,6 +81,8 @@ namespace Newtonsoft.Json.Tests.Documentation
Product deserializedProduct = JsonConvert.DeserializeObject(output);
#endregion
+
+ Assert.AreEqual("Apple", deserializedProduct.Name);
}
public void JsonSerializerToStream()
@@ -175,6 +179,7 @@ namespace Newtonsoft.Json.Tests.Documentation
}
#endregion
+ [Test]
public void SerializationCallbacksExample()
{
#region SerializationCallbacksExample
@@ -216,8 +221,11 @@ namespace Newtonsoft.Json.Tests.Documentation
Console.WriteLine(obj.Member4);
// This value was set after deserialization.
#endregion
+
+ Assert.AreEqual(11, obj.Member1);
}
+ [Test]
public void SerializationErrorHandling()
{
#region SerializationErrorHandling
@@ -251,8 +259,11 @@ namespace Newtonsoft.Json.Tests.Documentation
// Unexpected token parsing date. Expected String, got StartArray.
// Cannot convert null value to System.DateTime.
#endregion
+
+ Assert.AreEqual(new DateTime(2009, 9, 9, 0, 0, 0, DateTimeKind.Utc), c[0]);
}
+ [Test]
public void SerializationErrorHandlingWithParent()
{
#region SerializationErrorHandlingWithParent
@@ -302,6 +313,7 @@ namespace Newtonsoft.Json.Tests.Documentation
}
#endregion
+ [Test]
public void SerializationErrorHandlingAttributeExample()
{
#region SerializationErrorHandlingAttributeExample
@@ -322,6 +334,12 @@ namespace Newtonsoft.Json.Tests.Documentation
// "Title": "Mister Manager"
//}
#endregion
+
+ StringAssert.AreEqual(@"{
+ ""Name"": ""George Michael Bluth"",
+ ""Age"": 16,
+ ""Title"": ""Mister Manager""
+}", json);
}
public void PreservingObjectReferencesOff()
@@ -352,11 +370,33 @@ namespace Newtonsoft.Json.Tests.Documentation
// }
//]
#endregion
+
+ StringAssert.AreEqual(@"[
+ {
+ ""Name"": ""James"",
+ ""BirthDate"": ""1980-12-23T00:00:00Z"",
+ ""LastModified"": ""2009-02-20T12:59:21Z""
+ },
+ {
+ ""Name"": ""James"",
+ ""BirthDate"": ""1980-12-23T00:00:00Z"",
+ ""LastModified"": ""2009-02-20T12:59:21Z""
+ }
+]", json);
}
+ [Test]
public void PreservingObjectReferencesOn()
{
- List people = new List();
+ Person p = new Person
+ {
+ Name = "James"
+ };
+ List people = new List
+ {
+ p,
+ p
+ };
#region PreservingObjectReferencesOn
string json = JsonConvert.SerializeObject(people, Formatting.Indented,
@@ -391,6 +431,8 @@ namespace Newtonsoft.Json.Tests.Documentation
bool equal = Object.ReferenceEquals(p1, p2);
// true
#endregion
+
+ Assert.AreEqual(true, equal);
}
#region PreservingObjectReferencesAttribute
@@ -429,9 +471,25 @@ namespace Newtonsoft.Json.Tests.Documentation
}
#endregion
+ [Test]
public void CustomCreationConverterExample()
{
- string json = null;
+ string json = @"[
+ {
+ ""FirstName"": ""Maurice"",
+ ""LastName"": ""Moss"",
+ ""BirthDate"": ""1981-03-08T00:00Z"",
+ ""Department"": ""IT"",
+ ""JobTitle"": ""Support""
+ },
+ {
+ ""FirstName"": ""Jen"",
+ ""LastName"": ""Barber"",
+ ""BirthDate"": ""1985-12-10T00:00Z"",
+ ""Department"": ""IT"",
+ ""JobTitle"": ""Manager""
+ }
+]";
#region CustomCreationConverterExample
//[
@@ -466,8 +524,11 @@ namespace Newtonsoft.Json.Tests.Documentation
Console.WriteLine(employee.JobTitle);
// Support
#endregion
+
+ Assert.AreEqual("Support", employee.JobTitle);
}
+ [Test]
public void ContractResolver()
{
#region ContractResolver
@@ -488,7 +549,7 @@ namespace Newtonsoft.Json.Tests.Documentation
//{
// "name": "Widget",
- // "expiryDate": "2010-12-20T18:01Z",
+ // "expiryDate": "2010-12-20T18:01:00Z",
// "price": 9.99,
// "sizes": [
// "Small",
@@ -497,8 +558,20 @@ namespace Newtonsoft.Json.Tests.Documentation
// ]
//}
#endregion
+
+ Assert.AreEqual(@"{
+ ""name"": ""Widget"",
+ ""expiryDate"": ""2010-12-20T18:01:00Z"",
+ ""price"": 9.99,
+ ""sizes"": [
+ ""Small"",
+ ""Medium"",
+ ""Large""
+ ]
+}", json);
}
+ [Test]
public void SerializingCollectionsSerializing()
{
#region SerializingCollectionsSerializing
@@ -523,20 +596,36 @@ namespace Newtonsoft.Json.Tests.Documentation
//[
// {
// "Name": "Product 1",
- // "ExpiryDate": "2000-12-29T00:00Z",
+ // "ExpiryDate": "2000-12-29T00:00:00Z",
// "Price": 99.95,
// "Sizes": null
// },
// {
// "Name": "Product 2",
- // "ExpiryDate": "2009-07-31T00:00Z",
+ // "ExpiryDate": "2009-07-31T00:00:00Z",
// "Price": 12.50,
// "Sizes": null
// }
//]
#endregion
+
+ Assert.AreEqual(@"[
+ {
+ ""Name"": ""Product 1"",
+ ""ExpiryDate"": ""2000-12-29T00:00:00Z"",
+ ""Price"": 99.95,
+ ""Sizes"": null
+ },
+ {
+ ""Name"": ""Product 2"",
+ ""ExpiryDate"": ""2009-07-31T00:00:00Z"",
+ ""Price"": 12.50,
+ ""Sizes"": null
+ }
+]", json);
}
+ [Test]
public void SerializingCollectionsDeserializing()
{
#region SerializingCollectionsDeserializing
@@ -565,8 +654,11 @@ namespace Newtonsoft.Json.Tests.Documentation
Console.WriteLine(p1.Name);
// Product 1
#endregion
+
+ Assert.AreEqual("Product 1", p1.Name);
}
+ [Test]
public void SerializingCollectionsDeserializingDictionaries()
{
#region SerializingCollectionsDeserializingDictionaries
@@ -580,6 +672,8 @@ namespace Newtonsoft.Json.Tests.Documentation
Console.WriteLine(values["key1"]);
// value1
#endregion
+
+ Assert.AreEqual("value1", values["key1"]);
}
#region SerializingDatesInJson
@@ -658,6 +752,7 @@ namespace Newtonsoft.Json.Tests.Documentation
}
#endregion
+ [Test]
public void ReducingSerializedJsonSizeNullValueHandlingExample()
{
#region ReducingSerializedJsonSizeNullValueHandlingExample
@@ -687,6 +782,20 @@ namespace Newtonsoft.Json.Tests.Documentation
// "Description": "It's no Bad Boys"
// }
#endregion
+
+ Assert.AreEqual(@"{
+ ""Name"": ""Bad Boys III"",
+ ""Description"": ""It's no Bad Boys"",
+ ""Classification"": null,
+ ""Studio"": null,
+ ""ReleaseDate"": null,
+ ""ReleaseCountries"": null
+}", included);
+
+ Assert.AreEqual(@"{
+ ""Name"": ""Bad Boys III"",
+ ""Description"": ""It's no Bad Boys""
+}", ignored);
}
#region ReducingSerializedJsonSizeDefaultValueHandlingObject
@@ -744,6 +853,20 @@ namespace Newtonsoft.Json.Tests.Documentation
// "Amount": 50.0
// }
#endregion
+
+ Assert.AreEqual(@"{
+ ""Company"": ""Acme Ltd."",
+ ""Amount"": 50.0,
+ ""Paid"": false,
+ ""PaidDate"": null,
+ ""FollowUpDays"": 30,
+ ""FollowUpEmailAddress"": """"
+}", included);
+
+ Assert.AreEqual(@"{
+ ""Company"": ""Acme Ltd."",
+ ""Amount"": 50.0
+}", included);
}
#region ReducingSerializedJsonSizeContractResolverObject
@@ -807,6 +930,17 @@ namespace Newtonsoft.Json.Tests.Documentation
// "BookPrice": 16.19
// }
#endregion
+
+ Assert.AreEqual(@"{
+ ""AuthorName"": ""Brandon Sanderson"",
+ ""AuthorAge"": 34,
+ ""AuthorCountry"": ""United States of America""
+}", startingWithA);
+
+ Assert.AreEqual(@"{
+ ""BookName"": ""The Gathering Storm"",
+ ""BookPrice"": 16.19
+}", startingWithB);
}
#region SerializingPartialJsonFragmentsObject
@@ -818,6 +952,7 @@ namespace Newtonsoft.Json.Tests.Documentation
}
#endregion
+ [Test]
public void SerializingPartialJsonFragmentsExample()
{
#region SerializingPartialJsonFragmentsExample
@@ -894,8 +1029,11 @@ namespace Newtonsoft.Json.Tests.Documentation
// Content = Self: Zoolander. Socialite Paris Hilton...
// Url = http://www.imdb.com/name/nm0385296/
#endregion
+
+ Assert.AreEqual("Paris Hilton - Wikipedia, the free encyclopedia", searchResults[0].Title);
}
+ [Test]
public void SerializeMultidimensionalArrayExample()
{
string[,] famousCouples = new string[,]
@@ -918,6 +1056,8 @@ namespace Newtonsoft.Json.Tests.Documentation
Console.WriteLine(deserialized[3, 0] + ", " + deserialized[3, 1]);
// Han, Leia
+
+ Assert.AreEqual("Han", deserialized[3, 0]);
}
}
}
diff --git a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs
index d043d7e0..853daeae 100644
--- a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs
+++ b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs
@@ -61,6 +61,126 @@ namespace Newtonsoft.Json.Tests
[TestFixture]
public class JsonTextReaderTest : TestFixtureBase
{
+ [Test]
+ public void Float_NaN_Read()
+ {
+ const string testJson = "{float: NaN}";
+
+ JsonTextReader reader = new JsonTextReader(new StringReader(testJson));
+
+ Assert.IsTrue(reader.Read());
+ Assert.IsTrue(reader.Read());
+ Assert.IsTrue(reader.Read());
+
+ Assert.AreEqual(JsonToken.Float, reader.TokenType);
+ Assert.AreEqual(double.NaN, reader.Value);
+
+ Assert.IsTrue(reader.Read());
+ Assert.IsFalse(reader.Read());
+ }
+
+ [Test]
+ public void Float_NaN_ReadAsInt32()
+ {
+ const string testJson = "{float: NaN}";
+
+ JsonTextReader reader = new JsonTextReader(new StringReader(testJson));
+
+ Assert.IsTrue(reader.Read());
+ Assert.IsTrue(reader.Read());
+
+ ExceptionAssert.Throws(() => reader.ReadAsInt32(), "Cannot read NaN value. Path 'float', line 1, position 11.");
+ }
+
+ [Test]
+ public void Float_NaNAndInifinity_ReadAsDouble()
+ {
+ const string testJson = @"[
+ NaN,
+ Infinity,
+ -Infinity
+]"; ;
+
+ JsonTextReader reader = new JsonTextReader(new StringReader(testJson));
+
+ Assert.IsTrue(reader.Read());
+
+ Assert.AreEqual(double.NaN, reader.ReadAsDouble());
+ Assert.AreEqual(JsonToken.Float, reader.TokenType);
+ Assert.AreEqual(double.NaN, reader.Value);
+
+ Assert.AreEqual(double.PositiveInfinity, reader.ReadAsDouble());
+ Assert.AreEqual(JsonToken.Float, reader.TokenType);
+ Assert.AreEqual(double.PositiveInfinity, reader.Value);
+
+ Assert.AreEqual(double.NegativeInfinity, reader.ReadAsDouble());
+ Assert.AreEqual(JsonToken.Float, reader.TokenType);
+ Assert.AreEqual(double.NegativeInfinity, reader.Value);
+
+ Assert.IsTrue(reader.Read());
+ Assert.IsFalse(reader.Read());
+ }
+
+ [Test]
+ public void Float_NaNAndInifinity_ReadAsString()
+ {
+ const string testJson = @"[
+ NaN,
+ Infinity,
+ -Infinity
+]"; ;
+
+ JsonTextReader reader = new JsonTextReader(new StringReader(testJson));
+
+ Assert.IsTrue(reader.Read());
+
+ Assert.AreEqual(JsonConvert.NaN, reader.ReadAsString());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual(JsonConvert.NaN, reader.Value);
+
+ Assert.AreEqual(JsonConvert.PositiveInfinity, reader.ReadAsString());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual(JsonConvert.PositiveInfinity, reader.Value);
+
+ Assert.AreEqual(JsonConvert.NegativeInfinity, reader.ReadAsString());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual(JsonConvert.NegativeInfinity, reader.Value);
+
+ Assert.IsTrue(reader.Read());
+ Assert.IsFalse(reader.Read());
+ }
+
+ [Test]
+ public void FloatParseHandling_ReadAsString()
+ {
+ string json = "[9223372036854775807, 1.7976931348623157E+308, 792281625142643375935439503.35, 792281625142643375935555555555555555555555555555555555555555555555555439503.35]";
+
+ JsonTextReader reader = new JsonTextReader(new StringReader(json));
+ reader.FloatParseHandling = Json.FloatParseHandling.Decimal;
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+ Assert.AreEqual("9223372036854775807", reader.ReadAsString());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("9223372036854775807", reader.Value);
+
+ Assert.AreEqual("1.7976931348623157E+308", reader.ReadAsString());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("1.7976931348623157E+308", reader.Value);
+
+ Assert.AreEqual("792281625142643375935439503.35", reader.ReadAsString());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("792281625142643375935439503.35", reader.Value);
+
+ Assert.AreEqual("792281625142643375935555555555555555555555555555555555555555555555555439503.35", reader.ReadAsString());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("792281625142643375935555555555555555555555555555555555555555555555555439503.35", reader.Value);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+ }
+
[Test]
public void LineInfoAndNewLines()
{
@@ -455,7 +575,7 @@ third line", jsonTextReader.Value);
Assert.IsTrue(reader.Read());
Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
- ExceptionAssert.Throws(() => reader.Read(), "Cannot read NaN as a decimal.");
+ ExceptionAssert.Throws(() => reader.Read(), "Cannot read NaN value. Path '', line 1, position 4.");
}
[Test]
diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs
index 1a54f5c1..e459fa1c 100644
--- a/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs
@@ -51,6 +51,20 @@ namespace Newtonsoft.Json.Tests.Linq
[TestFixture]
public class JTokenReaderTest : TestFixtureBase
{
+#if !(NET20 || NET35 || PORTABLE40 || PORTABLE)
+ [Test]
+ public void ConvertBigIntegerToDouble()
+ {
+ var jObject = JObject.Parse("{ maxValue:10000000000000000000}");
+
+ JsonReader reader = jObject.CreateReader();
+ Assert.IsTrue(reader.Read());
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(10000000000000000000d, reader.ReadAsDouble());
+ Assert.IsTrue(reader.Read());
+ }
+#endif
+
[Test]
public void ErrorTokenIndex()
{
diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs
index 4ca7519c..174ec9c1 100644
--- a/Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs
@@ -249,6 +249,100 @@ namespace Newtonsoft.Json.Tests.Linq
]", writer.Token.ToString());
}
+ [Test]
+ public void WriteTokenWithParent()
+ {
+ JObject o = new JObject
+ {
+ ["prop1"] = new JArray(1),
+ ["prop2"] = 1
+ };
+
+ JTokenWriter writer = new JTokenWriter();
+
+ writer.WriteStartArray();
+
+ writer.WriteToken(o.CreateReader());
+
+ Assert.AreEqual(WriteState.Array, writer.WriteState);
+
+ writer.WriteEndArray();
+
+ Console.WriteLine(writer.Token.ToString());
+
+ StringAssert.AreEqual(@"[
+ {
+ ""prop1"": [
+ 1
+ ],
+ ""prop2"": 1
+ }
+]", writer.Token.ToString());
+ }
+
+ [Test]
+ public void WriteTokenWithPropertyParent()
+ {
+ JValue v = new JValue(1);
+
+ JTokenWriter writer = new JTokenWriter();
+
+ writer.WriteStartObject();
+ writer.WritePropertyName("Prop1");
+
+ writer.WriteToken(v.CreateReader());
+
+ Assert.AreEqual(WriteState.Object, writer.WriteState);
+
+ writer.WriteEndObject();
+
+ StringAssert.AreEqual(@"{
+ ""Prop1"": 1
+}", writer.Token.ToString());
+ }
+
+ [Test]
+ public void WriteValueTokenWithParent()
+ {
+ JValue v = new JValue(1);
+
+ JTokenWriter writer = new JTokenWriter();
+
+ writer.WriteStartArray();
+
+ writer.WriteToken(v.CreateReader());
+
+ Assert.AreEqual(WriteState.Array, writer.WriteState);
+
+ writer.WriteEndArray();
+
+ StringAssert.AreEqual(@"[
+ 1
+]", writer.Token.ToString());
+ }
+
+ [Test]
+ public void WriteEmptyToken()
+ {
+ JObject o = new JObject();
+ JsonReader reader = o.CreateReader();
+ while (reader.Read())
+ {
+ }
+
+ JTokenWriter writer = new JTokenWriter();
+
+ writer.WriteStartArray();
+
+ writer.WriteToken(reader);
+
+ Assert.AreEqual(WriteState.Array, writer.WriteState);
+
+ writer.WriteEndArray();
+
+ StringAssert.AreEqual(@"[]", writer.Token.ToString());
+ }
+
[Test]
public void WriteRawValue()
{
diff --git a/Src/Newtonsoft.Json.Tests/Linq/JsonPath/JPathExecuteTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JsonPath/JPathExecuteTests.cs
index 49f473d0..81c6cdc1 100644
--- a/Src/Newtonsoft.Json.Tests/Linq/JsonPath/JPathExecuteTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Linq/JsonPath/JPathExecuteTests.cs
@@ -902,5 +902,52 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
Assert.AreEqual("Headlight Fluid", firstProductNames[1]);
Assert.AreEqual(149.95m, totalPrice);
}
+
+ [Test]
+ public void NotEqualsAndNonPrimativeValues()
+ {
+ string json = @"[
+ {
+ ""name"": ""string"",
+ ""value"": ""aString""
+ },
+ {
+ ""name"": ""number"",
+ ""value"": 123
+ },
+ {
+ ""name"": ""array"",
+ ""value"": [
+ 1,
+ 2,
+ 3,
+ 4
+ ]
+ },
+ {
+ ""name"": ""object"",
+ ""value"": {
+ ""1"": 1
+ }
+ }
+]";
+
+ JArray a = JArray.Parse(json);
+
+ List result = a.SelectTokens("$.[?(@.value!=1)]").ToList();
+ Assert.AreEqual(4, result.Count);
+
+ result = a.SelectTokens("$.[?(@.value!='2000-12-05T05:07:59-10:00')]").ToList();
+ Assert.AreEqual(4, result.Count);
+
+ result = a.SelectTokens("$.[?(@.value!=null)]").ToList();
+ Assert.AreEqual(4, result.Count);
+
+ result = a.SelectTokens("$.[?(@.value!=123)]").ToList();
+ Assert.AreEqual(3, result.Count);
+
+ result = a.SelectTokens("$.[?(@.value)]").ToList();
+ Assert.AreEqual(4, result.Count);
+ }
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs b/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs
index a9b7f569..5ac8c2eb 100644
--- a/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs
@@ -55,6 +55,46 @@ namespace Newtonsoft.Json.Tests.Linq
[TestFixture]
public class LinqToJsonTest : TestFixtureBase
{
+ [Test]
+ public void FromObjectGuid()
+ {
+ var token1 = new JValue(Guid.NewGuid());
+ var token2 = JToken.FromObject(token1);
+ Assert.IsTrue(JToken.DeepEquals(token1, token2));
+ Assert.AreEqual(token1.Type, token2.Type);
+ }
+
+ [Test]
+ public void FromObjectTimeSpan()
+ {
+ var token1 = new JValue(TimeSpan.FromDays(1));
+ var token2 = JToken.FromObject(token1);
+ Assert.IsTrue(JToken.DeepEquals(token1, token2));
+ Assert.AreEqual(token1.Type, token2.Type);
+ }
+
+ [Test]
+ public void FromObjectUri()
+ {
+ var token1 = new JValue(new Uri("http://www.newtonsoft.com"));
+ var token2 = JToken.FromObject(token1);
+ Assert.IsTrue(JToken.DeepEquals(token1, token2));
+ Assert.AreEqual(token1.Type, token2.Type);
+ }
+
+ [Test]
+ public void ToObject_Guid()
+ {
+ JObject anon = new JObject
+ {
+ ["id"] = Guid.NewGuid()
+ };
+ Assert.AreEqual(JTokenType.Guid, anon["id"].Type);
+
+ Dictionary dict = anon.ToObject>();
+ Assert.AreEqual(JTokenType.Guid, dict["id"].Type);
+ }
+
public class TestClass_ULong
{
public ulong Value { get; set; }
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Dotnet.xproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Dotnet.xproj
index f3c3d980..e2efa374 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Dotnet.xproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Dotnet.xproj
@@ -9,9 +9,8 @@
13e906ae-5a47-4354-8caf-e63e8ac541ed
Newtonsoft.Json.Tests
..\artifacts\obj\$(MSBuildProjectName)
- ..\artifacts\bin\$(MSBuildProjectName)\
+ .\bin\
-
2.0
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj
index 648bf706..c8c6da9b 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj
@@ -171,15 +171,15 @@
-
+
-
-
-
-
+
+
+
+
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj
index d5fa425b..9c34acac 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj
@@ -202,12 +202,12 @@
-
-
+
+
-
+
@@ -232,8 +232,8 @@
-
-
+
+
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net40.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net40.csproj
index f0cdaacf..fc5de9b0 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net40.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net40.csproj
@@ -318,7 +318,7 @@
-
+
@@ -346,10 +346,10 @@
-
-
-
-
+
+
+
+
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable.csproj
index b39e015c..d1fcb3f5 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable.csproj
@@ -193,7 +193,7 @@
-
+
@@ -221,10 +221,10 @@
-
-
-
-
+
+
+
+
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable40.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable40.csproj
index 0b84de7d..ddc70846 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable40.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable40.csproj
@@ -197,7 +197,7 @@
-
+
@@ -225,10 +225,10 @@
-
-
-
-
+
+
+
+
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
index 0d74f34c..c8e864e2 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
@@ -383,7 +383,7 @@
-
+
@@ -392,10 +392,10 @@
-
-
-
-
+
+
+
+
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.project.json b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.project.json
index 51db2f8c..ffdaaa2c 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.project.json
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.project.json
@@ -3,7 +3,7 @@
"Autofac": "4.0.0-beta7-130",
"FSharp.Core": "4.0.0.1",
"NUnit": "2.6.2",
- "System.Buffers": "4.0.0-rc2-23826",
+ "System.Buffers": "4.0.0-rc2-24027",
"System.Collections.Immutable": "1.1.37"
},
"frameworks": {
diff --git a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
index 16f39448..7fdd7ec7 100644
--- a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
+++ b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
@@ -23,10 +23,9 @@
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
-#if !(NET20 || NET35 || NET40 || NETFX_CORE || PORTABLE || PORTABLE40 || DNXCORE50)
+#if !(NET20 || NET35 || NET40 || NETFX_CORE || PORTABLE40 || DNXCORE50)
using System.Xml;
using System;
-using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
@@ -258,6 +257,7 @@ namespace Newtonsoft.Json.Tests
}
#if !(PORTABLE40)
+#if !(PORTABLE)
[Test]
public void ConvertXmlNode()
{
@@ -269,6 +269,7 @@ namespace Newtonsoft.Json.Tests
JsonConvert.SerializeXmlNode(doc);
}
+#endif
[Test]
public void ConvertXNode()
@@ -301,6 +302,77 @@ namespace Newtonsoft.Json.Tests
return result;
}
+ [Test]
+ public void LargeArrayJTokenPathPerformance()
+ {
+ JArray a = new JArray();
+ for (int i = 0; i < 100000; i++)
+ {
+ a.Add(i);
+ }
+
+ JToken first = a.First;
+ JToken last = a.Last;
+
+ int interations = 1000;
+
+ TimeOperation(() =>
+ {
+ string p = null;
+ for (int i = 0; i < interations; i++)
+ {
+ p = first.Path;
+ }
+
+ return p;
+ }, "First");
+
+ TimeOperation(() =>
+ {
+ string p = null;
+ for (int i = 0; i < interations; i++)
+ {
+ p = last.Path;
+ }
+
+ return p;
+ }, "Last");
+ }
+
+ [Test]
+ public void LargeArrayAddPerformance()
+ {
+ JArray a1 = new JArray();
+
+ JArray a2 = new JArray();
+ for (int i = 0; i < 100000; i++)
+ {
+ a2.Add(i);
+ }
+
+ int interations = 1000;
+
+ TimeOperation(() =>
+ {
+ for (int i = 0; i < interations; i++)
+ {
+ a1.Add(interations);
+ }
+
+ return a1;
+ }, "Small");
+
+ TimeOperation(() =>
+ {
+ for (int i = 0; i < interations; i++)
+ {
+ a2.Add(interations);
+ }
+
+ return a2;
+ }, "Large");
+ }
+
[Test]
public void BuildJObject()
{
diff --git a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs
index 846978b1..9356d94e 100644
--- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs
+++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs
@@ -31,7 +31,9 @@ using System.Security;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-#if PORTABLE40
+#if NETSTANDARD10
+[assembly: AssemblyTitle("Json.NET Tests .NET Standard 1.0")]
+#elif PORTABLE40
[assembly: AssemblyTitle("Json.NET Tests Portable .NET 4.0")]
#elif PORTABLE
[assembly: AssemblyTitle("Json.NET Tests Portable")]
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs
index c00cca5e..ca4538b8 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs
@@ -77,22 +77,22 @@ namespace Newtonsoft.Json.Tests.Serialization
}
[Test]
- public void FailWithPrivateConstructorPlusParametizedAndDefault()
+ public void FailWithPrivateConstructorPlusParameterizedAndDefault()
{
ExceptionAssert.Throws(() =>
{
string json = @"{Name:""Name!""}";
- PrivateConstructorWithPublicParametizedConstructorTestClass c = JsonConvert.DeserializeObject(json);
+ PrivateConstructorWithPublicParameterizedConstructorTestClass c = JsonConvert.DeserializeObject(json);
});
}
[Test]
- public void SuccessWithPrivateConstructorPlusParametizedAndAllowNonPublic()
+ public void SuccessWithPrivateConstructorPlusParameterizedAndAllowNonPublic()
{
string json = @"{Name:""Name!""}";
- PrivateConstructorWithPublicParametizedConstructorTestClass c = JsonConvert.DeserializeObject(json,
+ PrivateConstructorWithPublicParameterizedConstructorTestClass c = JsonConvert.DeserializeObject(json,
new JsonSerializerSettings
{
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
@@ -103,71 +103,71 @@ namespace Newtonsoft.Json.Tests.Serialization
}
[Test]
- public void SuccessWithPublicParametizedConstructor()
+ public void SuccessWithPublicParameterizedConstructor()
{
string json = @"{Name:""Name!""}";
- var c = JsonConvert.DeserializeObject(json);
+ var c = JsonConvert.DeserializeObject(json);
Assert.IsNotNull(c);
Assert.AreEqual("Name!", c.Name);
}
[Test]
- public void SuccessWithPublicParametizedConstructorWhenParamaterIsNotAProperty()
+ public void SuccessWithPublicParameterizedConstructorWhenParameterIsNotAProperty()
{
string json = @"{nameParameter:""Name!""}";
- PublicParametizedConstructorWithNonPropertyParameterTestClass c = JsonConvert.DeserializeObject(json);
+ PublicParameterizedConstructorWithNonPropertyParameterTestClass c = JsonConvert.DeserializeObject(json);
Assert.IsNotNull(c);
Assert.AreEqual("Name!", c.Name);
}
[Test]
- public void SuccessWithPublicParametizedConstructorWhenParamaterRequiresAConverter()
+ public void SuccessWithPublicParameterizedConstructorWhenParameterRequiresAConverter()
{
string json = @"{nameParameter:""Name!""}";
- PublicParametizedConstructorRequiringConverterTestClass c = JsonConvert.DeserializeObject(json, new NameContainerConverter());
+ PublicParameterizedConstructorRequiringConverterTestClass c = JsonConvert.DeserializeObject(json, new NameContainerConverter());
Assert.IsNotNull(c);
Assert.AreEqual("Name!", c.Name.Value);
}
[Test]
- public void SuccessWithPublicParametizedConstructorWhenParamaterRequiresAConverterWithParameterAttribute()
+ public void SuccessWithPublicParameterizedConstructorWhenParameterRequiresAConverterWithParameterAttribute()
{
string json = @"{nameParameter:""Name!""}";
- PublicParametizedConstructorRequiringConverterWithParameterAttributeTestClass c = JsonConvert.DeserializeObject(json);
+ PublicParameterizedConstructorRequiringConverterWithParameterAttributeTestClass c = JsonConvert.DeserializeObject(json);
Assert.IsNotNull(c);
Assert.AreEqual("Name!", c.Name.Value);
}
[Test]
- public void SuccessWithPublicParametizedConstructorWhenParamaterRequiresAConverterWithPropertyAttribute()
+ public void SuccessWithPublicParameterizedConstructorWhenParameterRequiresAConverterWithPropertyAttribute()
{
string json = @"{name:""Name!""}";
- PublicParametizedConstructorRequiringConverterWithPropertyAttributeTestClass c = JsonConvert.DeserializeObject(json);
+ PublicParameterizedConstructorRequiringConverterWithPropertyAttributeTestClass c = JsonConvert.DeserializeObject(json);
Assert.IsNotNull(c);
Assert.AreEqual("Name!", c.Name.Value);
}
[Test]
- public void SuccessWithPublicParametizedConstructorWhenParamaterNameConflictsWithPropertyName()
+ public void SuccessWithPublicParameterizedConstructorWhenParameterNameConflictsWithPropertyName()
{
string json = @"{name:""1""}";
- PublicParametizedConstructorWithPropertyNameConflict c = JsonConvert.DeserializeObject(json);
+ PublicParameterizedConstructorWithPropertyNameConflict c = JsonConvert.DeserializeObject(json);
Assert.IsNotNull(c);
Assert.AreEqual(1, c.Name);
}
[Test]
- public void PublicParametizedConstructorWithPropertyNameConflictWithAttribute()
+ public void PublicParameterizedConstructorWithPropertyNameConflictWithAttribute()
{
string json = @"{name:""1""}";
- PublicParametizedConstructorWithPropertyNameConflictWithAttribute c = JsonConvert.DeserializeObject(json);
+ PublicParameterizedConstructorWithPropertyNameConflictWithAttribute c = JsonConvert.DeserializeObject(json);
Assert.IsNotNull(c);
Assert.AreEqual(1, c.Name);
}
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs
index 85b3f3ea..f0b9ed75 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs
@@ -441,12 +441,12 @@ namespace Newtonsoft.Json.Tests.Serialization
public void ParameterizedCreator()
{
var resolver = new DefaultContractResolver();
- var contract = (JsonObjectContract)resolver.ResolveContract(typeof(PublicParametizedConstructorWithPropertyNameConflictWithAttribute));
+ var contract = (JsonObjectContract)resolver.ResolveContract(typeof(PublicParameterizedConstructorWithPropertyNameConflictWithAttribute));
Assert.IsNull(contract.DefaultCreator);
Assert.IsNotNull(contract.ParameterizedCreator);
#pragma warning disable 618
- Assert.AreEqual(contract.ParametrizedConstructor, typeof(PublicParametizedConstructorWithPropertyNameConflictWithAttribute).GetConstructor(new[] { typeof(string) }));
+ Assert.AreEqual(contract.ParametrizedConstructor, typeof(PublicParameterizedConstructorWithPropertyNameConflictWithAttribute).GetConstructor(new[] { typeof(string) }));
#pragma warning restore 618
Assert.AreEqual(1, contract.CreatorParameters.Count);
Assert.AreEqual("name", contract.CreatorParameters[0].PropertyName);
@@ -461,12 +461,12 @@ namespace Newtonsoft.Json.Tests.Serialization
public void OverrideCreator()
{
var resolver = new DefaultContractResolver();
- var contract = (JsonObjectContract)resolver.ResolveContract(typeof(MultipleParamatrizedConstructorsJsonConstructor));
+ var contract = (JsonObjectContract)resolver.ResolveContract(typeof(MultipleParametrizedConstructorsJsonConstructor));
Assert.IsNull(contract.DefaultCreator);
Assert.IsNotNull(contract.OverrideCreator);
#pragma warning disable 618
- Assert.AreEqual(contract.OverrideConstructor, typeof(MultipleParamatrizedConstructorsJsonConstructor).GetConstructor(new[] { typeof(string), typeof(int) }));
+ Assert.AreEqual(contract.OverrideConstructor, typeof(MultipleParametrizedConstructorsJsonConstructor).GetConstructor(new[] { typeof(string), typeof(int) }));
#pragma warning restore 618
Assert.AreEqual(2, contract.CreatorParameters.Count);
Assert.AreEqual("Value", contract.CreatorParameters[0].PropertyName);
@@ -482,20 +482,20 @@ namespace Newtonsoft.Json.Tests.Serialization
public void CustomOverrideCreator()
{
var resolver = new DefaultContractResolver();
- var contract = (JsonObjectContract)resolver.ResolveContract(typeof(MultipleParamatrizedConstructorsJsonConstructor));
+ var contract = (JsonObjectContract)resolver.ResolveContract(typeof(MultipleParametrizedConstructorsJsonConstructor));
bool ensureCustomCreatorCalled = false;
contract.OverrideCreator = args =>
{
ensureCustomCreatorCalled = true;
- return new MultipleParamatrizedConstructorsJsonConstructor((string)args[0], (int)args[1]);
+ return new MultipleParametrizedConstructorsJsonConstructor((string)args[0], (int)args[1]);
};
#pragma warning disable 618
Assert.IsNull(contract.OverrideConstructor);
#pragma warning restore 618
- var o = JsonConvert.DeserializeObject("{Value:'value!', Age:1}", new JsonSerializerSettings
+ var o = JsonConvert.DeserializeObject("{Value:'value!', Age:1}", new JsonSerializerSettings
{
ContractResolver = resolver
});
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs
index 8f4a0a62..ec1092f4 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs
@@ -27,7 +27,7 @@ using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.Serialization;
-#if !(NET20 || NET35 || NETFX_CORE || PORTABLE)
+#if !(NET20 || NET35 || NETFX_CORE || PORTABLE || DNXCORE50)
using System.Runtime.Serialization.Json;
#endif
using System.Text;
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs
index 6acc24df..0a366552 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs
@@ -374,6 +374,40 @@ namespace Newtonsoft.Json.Tests.Serialization
Assert.AreEqual(7, c.ExtensionData.Count);
}
+ [JsonObject(MemberSerialization.OptIn)]
+ public class MyClass
+ {
+ public int NotForJson { get; set; }
+
+ [JsonPropertyAttribute(Required = Required.Always)]
+ public int ForJson { get; set; }
+
+ [JsonExtensionData(ReadData = true, WriteData = true)]
+ public IDictionary ExtraInfoJson { get; set; }
+
+ public MyClass(MyClass other = null)
+ {
+ if (other != null)
+ {
+ // copy construct
+ }
+ }
+ }
+
+ [Test]
+ public void PopulateWithExtensionData()
+ {
+ string jsonStirng = @"{ ""ForJson"" : 33 , ""extra1"" : 11, ""extra2"" : 22 }";
+
+ MyClass c = new MyClass();
+
+ JsonConvert.PopulateObject(jsonStirng, c);
+
+ Assert.AreEqual(2, c.ExtraInfoJson.Count);
+ Assert.AreEqual(11, (int)c.ExtraInfoJson["extra1"]);
+ Assert.AreEqual(22, (int)c.ExtraInfoJson["extra2"]);
+ }
+
public class MultipleExtensionDataAttributesTestClass
{
public string Name { get; set; }
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs
index a7196a4d..b71149ea 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs
@@ -1917,6 +1917,86 @@ namespace Newtonsoft.Json.Tests.Serialization
Assert.AreEqual(deserializeTest2["testkey"], "");
}
#endif
+
+ [Test]
+ public void DeserializeCollectionWithConstructorArrayArgument()
+ {
+ var v = new ReadOnlyCollectionWithArrayArgument(new[] { -0.014147478859765236, -0.011419606805541858, -0.010038461483676238 });
+ var json = JsonConvert.SerializeObject(v);
+
+ ExceptionAssert.Throws(() =>
+ {
+ JsonConvert.DeserializeObject>(json);
+ }, "Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.ReadOnlyCollectionWithArrayArgument`1[System.Double]. Path '', line 1, position 1.");
+ }
+ }
+
+ public class ReadOnlyCollectionWithArrayArgument : IList
+ {
+ private readonly IList _values;
+
+ public ReadOnlyCollectionWithArrayArgument(T[] args)
+ {
+ _values = args ?? (IList)new List();
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return _values.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return _values.GetEnumerator();
+ }
+
+ public void Add(T item)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Clear()
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool Contains(T item)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void CopyTo(T[] array, int arrayIndex)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool Remove(T item)
+ {
+ throw new NotImplementedException();
+ }
+
+ public int Count { get; }
+ public bool IsReadOnly { get; }
+ public int IndexOf(T item)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Insert(int index, T item)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveAt(int index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T this[int index]
+ {
+ get { throw new NotImplementedException(); }
+ set { throw new NotImplementedException(); }
+ }
}
#if !(NET40 || NET35 || NET20 || PORTABLE40)
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
index cb37f805..53fc1fa1 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
@@ -5286,7 +5286,7 @@ Path '', line 1, position 1.");
}
#endif
-#if !NETFX_CORE
+#if !(NETFX_CORE || DNXCORE50)
public class XmlNodeTestObject
{
public XmlDocument Document { get; set; }
@@ -6104,15 +6104,15 @@ Path '', line 1, position 1.");
public void PublicConstructorOverridenByJsonConstructorTest()
{
PublicConstructorOverridenByJsonConstructor c = JsonConvert.DeserializeObject("{Value:'value!'}");
- Assert.AreEqual("Public Paramatized", c.Constructor);
+ Assert.AreEqual("Public Parameterized", c.Constructor);
Assert.AreEqual("value!", c.Value);
}
[Test]
- public void MultipleParamatrizedConstructorsJsonConstructorTest()
+ public void MultipleParametrizedConstructorsJsonConstructorTest()
{
- MultipleParamatrizedConstructorsJsonConstructor c = JsonConvert.DeserializeObject("{Value:'value!', Age:1}");
- Assert.AreEqual("Public Paramatized 2", c.Constructor);
+ MultipleParametrizedConstructorsJsonConstructor c = JsonConvert.DeserializeObject("{Value:'value!', Age:1}");
+ Assert.AreEqual("Public Parameterized 2", c.Constructor);
Assert.AreEqual("value!", c.Value);
Assert.AreEqual(1, c.Age);
}
@@ -9760,7 +9760,7 @@ Path '', line 1, position 1.");
public NonPublicConstructorWithJsonConstructor(string value)
{
Value = value;
- Constructor = "Public Paramatized";
+ Constructor = "Public Parameterized";
}
}
@@ -9803,28 +9803,28 @@ Path '', line 1, position 1.");
public PublicConstructorOverridenByJsonConstructor(string value)
{
Value = value;
- Constructor = "Public Paramatized";
+ Constructor = "Public Parameterized";
}
}
- public class MultipleParamatrizedConstructorsJsonConstructor
+ public class MultipleParametrizedConstructorsJsonConstructor
{
public string Value { get; private set; }
public int Age { get; private set; }
public string Constructor { get; private set; }
- public MultipleParamatrizedConstructorsJsonConstructor(string value)
+ public MultipleParametrizedConstructorsJsonConstructor(string value)
{
Value = value;
- Constructor = "Public Paramatized 1";
+ Constructor = "Public Parameterized 1";
}
[JsonConstructor]
- public MultipleParamatrizedConstructorsJsonConstructor(string value, int age)
+ public MultipleParametrizedConstructorsJsonConstructor(string value, int age)
{
Value = value;
Age = age;
- Constructor = "Public Paramatized 2";
+ Constructor = "Public Parameterized 2";
}
}
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/MetadataPropertyHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/MetadataPropertyHandlingTests.cs
index f413e85f..08c3c6b8 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/MetadataPropertyHandlingTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/MetadataPropertyHandlingTests.cs
@@ -528,6 +528,72 @@ namespace Newtonsoft.Json.Tests.Serialization
JObject o = (JObject)actual.Payload;
Assert.AreEqual("System.Byte[], mscorlib", (string)o["$type"]);
Assert.AreEqual("AAECAwQFBgcICQ==", (string)o["$value"]);
+ Assert.AreEqual(null, o.Parent);
+ }
+
+ [Test]
+ public void ReadAhead_JObject_NoParent()
+ {
+ ItemWithUntypedPayload actual = JsonConvert.DeserializeObject(@"{
+ ""Payload"": {}
+}",
+ new JsonSerializerSettings
+ {
+ MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead
+ });
+
+ JObject o = (JObject)actual.Payload;
+ Assert.AreEqual(null, o.Parent);
+ }
+
+ public class ItemWithJTokens
+ {
+ public JValue Payload1 { get; set; }
+ public JObject Payload2 { get; set; }
+ public JArray Payload3 { get; set; }
+ }
+
+ [Test]
+ public void ReadAhead_TypedJValue_NoParent()
+ {
+ ItemWithJTokens actual = (ItemWithJTokens)JsonConvert.DeserializeObject(@"{
+ ""Payload1"": 1,
+ ""Payload2"": {'prop1':1,'prop2':[2]},
+ ""Payload3"": [1],
+ ""$type"": ""Newtonsoft.Json.Tests.Serialization.MetadataPropertyHandlingTests+ItemWithJTokens, Newtonsoft.Json.Tests""
+}",
+ new JsonSerializerSettings
+ {
+ MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead,
+ TypeNameHandling = TypeNameHandling.All
+ });
+
+ Assert.AreEqual(JTokenType.Integer, actual.Payload1.Type);
+ Assert.AreEqual(1, (int)actual.Payload1);
+ Assert.AreEqual(null, actual.Payload1.Parent);
+
+ Assert.AreEqual(JTokenType.Object, actual.Payload2.Type);
+ Assert.AreEqual(1, (int)actual.Payload2["prop1"]);
+ Assert.AreEqual(2, (int)actual.Payload2["prop2"][0]);
+ Assert.AreEqual(null, actual.Payload2.Parent);
+
+ Assert.AreEqual(1, (int)actual.Payload3[0]);
+ Assert.AreEqual(null, actual.Payload3.Parent);
+ }
+
+ [Test]
+ public void ReadAhead_JArray_NoParent()
+ {
+ ItemWithUntypedPayload actual = JsonConvert.DeserializeObject(@"{
+ ""Payload"": [1]
+}",
+ new JsonSerializerSettings
+ {
+ MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead
+ });
+
+ JArray o = (JArray)actual.Payload;
+ Assert.AreEqual(null, o.Parent);
}
public class ItemWithUntypedPayload
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ReflectionAttributeProviderTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ReflectionAttributeProviderTests.cs
index dad49a58..d16dc63f 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/ReflectionAttributeProviderTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/ReflectionAttributeProviderTests.cs
@@ -71,7 +71,12 @@ namespace Newtonsoft.Json.Tests.Serialization
[Test]
public void GetAttributes_Property()
{
- PropertyInfo property = typeof(ReflectionTestObject).GetProperty("TestProperty");
+ PropertyInfo property;
+#if DNXCORE50
+ property = Newtonsoft.Json.Utilities.TypeExtensions.GetProperty(typeof(ReflectionTestObject), "TestProperty");
+#else
+ property = typeof(ReflectionTestObject).GetProperty("TestProperty");
+#endif
ReflectionAttributeProvider provider = new ReflectionAttributeProvider(property);
@@ -85,7 +90,12 @@ namespace Newtonsoft.Json.Tests.Serialization
[Test]
public void GetAttributes_Field()
{
- FieldInfo field = (FieldInfo)typeof(ReflectionTestObject).GetField("TestField");
+ FieldInfo field;
+#if DNXCORE50
+ field = (FieldInfo)Newtonsoft.Json.Utilities.TypeExtensions.GetField(typeof(ReflectionTestObject), "TestField");
+#else
+ field = typeof(ReflectionTestObject).GetField("TestField");
+#endif
ReflectionAttributeProvider provider = new ReflectionAttributeProvider(field);
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs
index 1844246f..a3099970 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs
@@ -74,11 +74,14 @@ namespace Newtonsoft.Json.Tests.Serialization
var possibleMsgs = new[]
{
"[1] - Error message for member 1 = An item with the same key has already been added.",
- "[1] - Error message for member 1 = An element with the same key already exists in the dictionary." // mono
+ "[1] - Error message for member 1 = An element with the same key already exists in the dictionary.", // mono
+ "[1] - Error message for member 1 = An item with the same key has already been added. Key: Jim" // netcore
};
VersionKeyedCollection c = JsonConvert.DeserializeObject(json);
Assert.AreEqual(1, c.Count);
Assert.AreEqual(1, c.Messages.Count);
+
+ Console.WriteLine(c.Messages[0]);
Assert.IsTrue(possibleMsgs.Any(m => m == c.Messages[0]), "Expected One of: " + Environment.NewLine + string.Join(Environment.NewLine, possibleMsgs) + Environment.NewLine + "Was: " + Environment.NewLine + c.Messages[0]);
}
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs
index 86d2a62f..e931c634 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs
@@ -733,7 +733,7 @@ Newtonsoft.Json Error: 0 : Error!
}
[Test]
- public void PublicParametizedConstructorWithPropertyNameConflictWithAttribute()
+ public void PublicParameterizedConstructorWithPropertyNameConflictWithAttribute()
{
InMemoryTraceWriter traceWriter = new InMemoryTraceWriter
{
@@ -742,7 +742,7 @@ Newtonsoft.Json Error: 0 : Error!
string json = @"{name:""1""}";
- PublicParametizedConstructorWithPropertyNameConflictWithAttribute c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings
+ PublicParameterizedConstructorWithPropertyNameConflictWithAttribute c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings
{
TraceWriter = traceWriter
});
@@ -750,7 +750,7 @@ Newtonsoft.Json Error: 0 : Error!
Assert.IsNotNull(c);
Assert.AreEqual(1, c.Name);
- Assert.AreEqual("Deserializing Newtonsoft.Json.Tests.TestObjects.PublicParametizedConstructorWithPropertyNameConflictWithAttribute using creator with parameters: name. Path 'name', line 1, position 6.", traceWriter.TraceRecords[0].Message);
+ Assert.AreEqual("Deserializing Newtonsoft.Json.Tests.TestObjects.PublicParameterizedConstructorWithPropertyNameConflictWithAttribute using creator with parameters: name. Path 'name', line 1, position 6.", traceWriter.TraceRecords[0].Message);
}
[Test]
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/WebApiIntegrationTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/WebApiIntegrationTests.cs
index 6e748b1c..915e837f 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/WebApiIntegrationTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/WebApiIntegrationTests.cs
@@ -41,7 +41,7 @@ using Assert = Newtonsoft.Json.Tests.XUnitAssert;
#else
using NUnit.Framework;
#endif
-#if !(NETFX_CORE || NET20 || NET35)
+#if !(NETFX_CORE || NET20 || NET35 || DNXCORE50)
using System.Runtime.Serialization.Json;
#endif
using Newtonsoft.Json.Serialization;
diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ListOfIds.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ListOfIds.cs
index 9333c511..23ef39cd 100644
--- a/Src/Newtonsoft.Json.Tests/TestObjects/ListOfIds.cs
+++ b/Src/Newtonsoft.Json.Tests/TestObjects/ListOfIds.cs
@@ -66,7 +66,11 @@ namespace Newtonsoft.Json.Tests.TestObjects
public override bool CanConvert(Type objectType)
{
+#if DNXCORE50
+ return Newtonsoft.Json.Utilities.TypeExtensions.IsAssignableFrom(typeof(IList), objectType);
+#else
return typeof(IList).IsAssignableFrom(objectType);
+#endif
}
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParametizedConstructorTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParameterizedConstructorTestClass.cs
similarity index 85%
rename from Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParametizedConstructorTestClass.cs
rename to Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParameterizedConstructorTestClass.cs
index d63748fc..56dabb52 100644
--- a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParametizedConstructorTestClass.cs
+++ b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParameterizedConstructorTestClass.cs
@@ -27,17 +27,17 @@ using System;
namespace Newtonsoft.Json.Tests.TestObjects
{
- public class PrivateConstructorWithPublicParametizedConstructorTestClass
+ public class PrivateConstructorWithPublicParameterizedConstructorTestClass
{
public string Name { get; set; }
public int Age { get; set; }
- private PrivateConstructorWithPublicParametizedConstructorTestClass()
+ private PrivateConstructorWithPublicParameterizedConstructorTestClass()
{
Age = 1;
}
- public PrivateConstructorWithPublicParametizedConstructorTestClass(string dummy)
+ public PrivateConstructorWithPublicParameterizedConstructorTestClass(string dummy)
{
throw new Exception("Should never get here.");
}
diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorRequiringConverterTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParameterizedConstructorRequiringConverterTestClass.cs
similarity index 81%
rename from Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorRequiringConverterTestClass.cs
rename to Src/Newtonsoft.Json.Tests/TestObjects/PublicParameterizedConstructorRequiringConverterTestClass.cs
index 31467032..e1e3d3eb 100644
--- a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorRequiringConverterTestClass.cs
+++ b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParameterizedConstructorRequiringConverterTestClass.cs
@@ -62,11 +62,11 @@ namespace Newtonsoft.Json.Tests.TestObjects
}
}
- public class PublicParametizedConstructorRequiringConverterTestClass
+ public class PublicParameterizedConstructorRequiringConverterTestClass
{
private readonly NameContainer _nameContainer;
- public PublicParametizedConstructorRequiringConverterTestClass(NameContainer nameParameter)
+ public PublicParameterizedConstructorRequiringConverterTestClass(NameContainer nameParameter)
{
_nameContainer = nameParameter;
}
@@ -77,11 +77,11 @@ namespace Newtonsoft.Json.Tests.TestObjects
}
}
- public class PublicParametizedConstructorRequiringConverterWithParameterAttributeTestClass
+ public class PublicParameterizedConstructorRequiringConverterWithParameterAttributeTestClass
{
private readonly NameContainer _nameContainer;
- public PublicParametizedConstructorRequiringConverterWithParameterAttributeTestClass([JsonConverter(typeof(NameContainerConverter))] NameContainer nameParameter)
+ public PublicParameterizedConstructorRequiringConverterWithParameterAttributeTestClass([JsonConverter(typeof(NameContainerConverter))] NameContainer nameParameter)
{
_nameContainer = nameParameter;
}
@@ -92,11 +92,11 @@ namespace Newtonsoft.Json.Tests.TestObjects
}
}
- public class PublicParametizedConstructorRequiringConverterWithPropertyAttributeTestClass
+ public class PublicParameterizedConstructorRequiringConverterWithPropertyAttributeTestClass
{
private readonly NameContainer _nameContainer;
- public PublicParametizedConstructorRequiringConverterWithPropertyAttributeTestClass(NameContainer name)
+ public PublicParameterizedConstructorRequiringConverterWithPropertyAttributeTestClass(NameContainer name)
{
_nameContainer = name;
}
diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParameterizedConstructorTestClass.cs
similarity index 91%
rename from Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorTestClass.cs
rename to Src/Newtonsoft.Json.Tests/TestObjects/PublicParameterizedConstructorTestClass.cs
index 24dd7871..c0dafbfa 100644
--- a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorTestClass.cs
+++ b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParameterizedConstructorTestClass.cs
@@ -25,11 +25,11 @@
namespace Newtonsoft.Json.Tests.TestObjects
{
- public class PublicParametizedConstructorTestClass
+ public class PublicParameterizedConstructorTestClass
{
private readonly string _name;
- public PublicParametizedConstructorTestClass(string name)
+ public PublicParameterizedConstructorTestClass(string name)
{
_name = name;
}
diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorWithNonPropertyParameterTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParameterizedConstructorWithNonPropertyParameterTestClass.cs
similarity index 88%
rename from Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorWithNonPropertyParameterTestClass.cs
rename to Src/Newtonsoft.Json.Tests/TestObjects/PublicParameterizedConstructorWithNonPropertyParameterTestClass.cs
index 6fb286f6..66e8caff 100644
--- a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorWithNonPropertyParameterTestClass.cs
+++ b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParameterizedConstructorWithNonPropertyParameterTestClass.cs
@@ -25,11 +25,11 @@
namespace Newtonsoft.Json.Tests.TestObjects
{
- public class PublicParametizedConstructorWithNonPropertyParameterTestClass
+ public class PublicParameterizedConstructorWithNonPropertyParameterTestClass
{
private readonly string _name;
- public PublicParametizedConstructorWithNonPropertyParameterTestClass(string nameParameter)
+ public PublicParameterizedConstructorWithNonPropertyParameterTestClass(string nameParameter)
{
_name = nameParameter;
}
diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorWithPropertyNameConflict.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParameterizedConstructorWithPropertyNameConflict.cs
similarity index 81%
rename from Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorWithPropertyNameConflict.cs
rename to Src/Newtonsoft.Json.Tests/TestObjects/PublicParameterizedConstructorWithPropertyNameConflict.cs
index 14b8c5cd..5bee1a6c 100644
--- a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorWithPropertyNameConflict.cs
+++ b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParameterizedConstructorWithPropertyNameConflict.cs
@@ -27,11 +27,11 @@ using System;
namespace Newtonsoft.Json.Tests.TestObjects
{
- public class PublicParametizedConstructorWithPropertyNameConflict
+ public class PublicParameterizedConstructorWithPropertyNameConflict
{
private readonly int _value;
- public PublicParametizedConstructorWithPropertyNameConflict(string name)
+ public PublicParameterizedConstructorWithPropertyNameConflict(string name)
{
_value = Convert.ToInt32(name);
}
@@ -42,11 +42,11 @@ namespace Newtonsoft.Json.Tests.TestObjects
}
}
- public class PublicParametizedConstructorWithPropertyNameConflictWithAttribute
+ public class PublicParameterizedConstructorWithPropertyNameConflictWithAttribute
{
private readonly int _value;
- public PublicParametizedConstructorWithPropertyNameConflictWithAttribute([JsonProperty("name")] string nameParameter)
+ public PublicParameterizedConstructorWithPropertyNameConflictWithAttribute([JsonProperty("name")] string nameParameter)
{
_value = Convert.ToInt32(nameParameter);
}
diff --git a/Src/Newtonsoft.Json.Tests/Utilities/DynamicReflectionDelegateFactoryTests.cs b/Src/Newtonsoft.Json.Tests/Utilities/DynamicReflectionDelegateFactoryTests.cs
index a4a93c52..3fc261d0 100644
--- a/Src/Newtonsoft.Json.Tests/Utilities/DynamicReflectionDelegateFactoryTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Utilities/DynamicReflectionDelegateFactoryTests.cs
@@ -175,6 +175,24 @@ namespace Newtonsoft.Json.Tests.Utilities
JsonSerializerTest.DictionaryKey key = (JsonSerializerTest.DictionaryKey)result;
Assert.AreEqual("First!", key.Value);
}
+
+ [Test]
+ public void CreatePropertyGetter()
+ {
+ PropertyInfo namePropertyInfo = typeof(Person).GetProperty(nameof(Person.Name));
+
+ Assert.IsNotNull(namePropertyInfo);
+
+ var call = DynamicReflectionDelegateFactory.Instance.CreateGet(namePropertyInfo);
+
+ Person p = new Person();
+ p.Name = "Name!";
+
+ object result = call(p);
+ Assert.IsNotNull(result);
+
+ Assert.AreEqual("Name!", (string)result);
+ }
}
}
diff --git a/Src/Newtonsoft.Json.Tests/Utilities/StringUtilsTests.cs b/Src/Newtonsoft.Json.Tests/Utilities/StringUtilsTests.cs
index ea5dd389..893776b1 100644
--- a/Src/Newtonsoft.Json.Tests/Utilities/StringUtilsTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Utilities/StringUtilsTests.cs
@@ -57,6 +57,7 @@ namespace Newtonsoft.Json.Tests.Utilities
Assert.AreEqual(" IPhone", StringUtils.ToCamelCase(" IPhone"));
Assert.AreEqual("isCIA", StringUtils.ToCamelCase("IsCIA"));
Assert.AreEqual("vmQ", StringUtils.ToCamelCase("VmQ"));
+ Assert.AreEqual("xml2Json", StringUtils.ToCamelCase("Xml2Json"));
}
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/project.json b/Src/Newtonsoft.Json.Tests/project.json
index 5c105e65..4c6f7b29 100644
--- a/Src/Newtonsoft.Json.Tests/project.json
+++ b/Src/Newtonsoft.Json.Tests/project.json
@@ -1,17 +1,13 @@
{
"version": "1.0.0-*",
- "exclude": [
- ],
"dependencies": {
"Newtonsoft.Json": {
"target": "project"
}
},
- "commands": {
- "test": "xunit.runner.dnx -parallel none"
- },
+ "testRunner": "xunit",
"frameworks": {
- "net45": {
+ /*"net45": {
"frameworkAssemblies": {
"System.Collections": "",
"System.ComponentModel.DataAnnotations": "",
@@ -38,7 +34,6 @@
},
"net40": {
"frameworkAssemblies": {
- "System.Collections": "",
"System.ComponentModel.DataAnnotations": "",
"System.Data": "",
"System.Data.DataSetExtensions": "",
@@ -46,7 +41,6 @@
"System.Data.Linq": "",
"System.Drawing": "",
"System.Numerics": "",
- "System.Runtime": "",
"System.Runtime.Serialization": "",
"System.Web": "",
"System.Web.Extensions": "",
@@ -87,40 +81,27 @@
"dependencies": {
"NUnit": "2.6.4"
}
- },
- "dnxcore50": {
+ },*/
+ "netcoreapp1.0": {
+ "buildOptions": {
+ "define": [ "NETSTANDARD10", "DNXCORE50", "PORTABLE" ]
+ },
"dependencies": {
- "Microsoft.CSharp": "4.0.0",
- "System.Collections": "4.0.10",
- "System.Collections.Immutable": "1.1.37",
- "System.ComponentModel.TypeConverter": "4.0.0",
- "System.Diagnostics.Debug": "4.0.10",
- "System.Dynamic.Runtime": "4.0.10",
- "System.Globalization": "4.0.10",
- "System.IO": "4.0.10",
- "System.Linq": "4.0.0",
- "System.Linq.Expressions": "4.0.10",
- "System.Reflection.Emit.ILGeneration": "4.0.0",
- "System.Reflection.Extensions": "4.0.0",
- "System.Reflection.TypeExtensions": "4.0.0",
- "System.Runtime": "4.0.20",
- "System.Runtime.Extensions": "4.0.10",
- "System.Runtime.Numerics": "4.0.0",
- "System.Runtime.Serialization.Json": "4.0.0",
- "System.Runtime.Serialization.Primitives": "4.0.10",
- "System.Runtime.Serialization.Xml": "4.0.10",
- "System.Text.Encoding": "4.0.10",
- "System.Text.Encoding.CodePages": "4.0.0",
- "System.Text.Encoding.Extensions": "4.0.10",
- "System.Text.RegularExpressions": "4.0.10",
- "System.Threading": "4.0.10",
- "System.Xml.ReaderWriter": "4.0.10",
- "System.Xml.XDocument": "4.0.10",
- "System.Xml.XmlDocument": "4.0.0",
- "System.Xml.XmlSerializer": "4.0.10",
- "xunit": "2.1.0-*",
- "xunit.runner.dnx": "2.1.0-rc1-build204"
- }
+ "Microsoft.NETCore.App": {
+ "type": "platform",
+ "version": "1.0.0-rc2-3002702"
+ },
+ "System.Runtime.Serialization.Primitives": "4.1.1-rc2-24027",
+ "System.Xml.XmlSerializer": "4.0.11-rc2-24027",
+ "System.Runtime.Serialization.Json": "4.0.2-rc2-24027",
+ "System.Runtime.Serialization.Xml": "4.1.1-rc2-24027",
+ "xunit": "2.1.0",
+ "dotnet-test-xunit": "1.0.0-rc2-build10015"
+ },
+ "imports": [
+ "dnxcore50",
+ "portable-net45+win8"
+ ]
}
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Bson/BsonReader.cs b/Src/Newtonsoft.Json/Bson/BsonReader.cs
index 0ea895a6..0c8559ed 100644
--- a/Src/Newtonsoft.Json/Bson/BsonReader.cs
+++ b/Src/Newtonsoft.Json/Bson/BsonReader.cs
@@ -178,7 +178,7 @@ namespace Newtonsoft.Json.Bson
/// Reads the next JSON token from the stream.
///
///
- /// true if the next token was read successfully; false if there are no more tokens to read.
+ /// true if the next token was read successfully; false if there are no more tokens to read.
///
public override bool Read()
{
diff --git a/Src/Newtonsoft.Json/ConstructorHandling.cs b/Src/Newtonsoft.Json/ConstructorHandling.cs
index e403f1e4..2455d61d 100644
--- a/Src/Newtonsoft.Json/ConstructorHandling.cs
+++ b/Src/Newtonsoft.Json/ConstructorHandling.cs
@@ -31,12 +31,12 @@ namespace Newtonsoft.Json
public enum ConstructorHandling
{
///
- /// First attempt to use the public default constructor, then fall back to single paramatized constructor, then the non-public default constructor.
+ /// First attempt to use the public default constructor, then fall back to single parameterized constructor, then the non-public default constructor.
///
Default = 0,
///
- /// Json.NET will use a non-public default constructor before falling back to a paramatized constructor.
+ /// Json.NET will use a non-public default constructor before falling back to a parameterized constructor.
///
AllowNonPublicDefaultConstructor = 1
}
diff --git a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
index 051f6768..d4dd7903 100644
--- a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
@@ -37,16 +37,9 @@ using Newtonsoft.Json.Serialization;
using System.Xml.Linq;
#endif
using Newtonsoft.Json.Utilities;
-#if NET20
-using Newtonsoft.Json.Utilities.LinqBridge;
-#else
-using System.Linq;
-
-#endif
namespace Newtonsoft.Json.Converters
{
-
#region XmlNodeWrappers
#if !DOTNET && !PORTABLE && !PORTABLE40
internal class XmlDocumentWrapper : XmlNodeWrapper, IXmlDocument
@@ -234,7 +227,8 @@ namespace Newtonsoft.Json.Converters
internal class XmlNodeWrapper : IXmlNode
{
private readonly XmlNode _node;
- private IList _childNodes;
+ private List _childNodes;
+ private List _attributes;
public XmlNodeWrapper(XmlNode node)
{
@@ -256,7 +250,7 @@ namespace Newtonsoft.Json.Converters
get { return _node.LocalName; }
}
- public IList ChildNodes
+ public List ChildNodes
{
get
{
@@ -264,7 +258,11 @@ namespace Newtonsoft.Json.Converters
// cache results to prevent multiple reads which kills perf in large documents
if (_childNodes == null)
{
- _childNodes = _node.ChildNodes.Cast().Select(WrapNode).ToList();
+ _childNodes = new List(_node.ChildNodes.Count);
+ foreach (XmlNode childNode in _node.ChildNodes)
+ {
+ _childNodes.Add(WrapNode(childNode));
+ }
}
return _childNodes;
@@ -286,7 +284,7 @@ namespace Newtonsoft.Json.Converters
}
}
- public IList Attributes
+ public List Attributes
{
get
{
@@ -295,7 +293,18 @@ namespace Newtonsoft.Json.Converters
return null;
}
- return _node.Attributes.Cast().Select(WrapNode).ToList();
+ // attributes is read multiple times
+ // cache results to prevent multiple reads which kills perf in large documents
+ if (_attributes == null)
+ {
+ _attributes = new List(_node.Attributes.Count);
+ foreach (XmlAttribute attribute in _node.Attributes)
+ {
+ _attributes.Add(WrapNode(attribute));
+ }
+ }
+
+ return _attributes;
}
}
@@ -327,6 +336,7 @@ namespace Newtonsoft.Json.Converters
XmlNodeWrapper xmlNodeWrapper = (XmlNodeWrapper)newChild;
_node.AppendChild(xmlNodeWrapper._node);
_childNodes = null;
+ _attributes = null;
return newChild;
}
@@ -384,8 +394,8 @@ namespace Newtonsoft.Json.Converters
{
XmlNodeType NodeType { get; }
string LocalName { get; }
- IList ChildNodes { get; }
- IList Attributes { get; }
+ List ChildNodes { get; }
+ List Attributes { get; }
IXmlNode ParentNode { get; }
string Value { get; set; }
IXmlNode AppendChild(IXmlNode newChild);
@@ -477,11 +487,11 @@ namespace Newtonsoft.Json.Converters
{
}
- public override IList ChildNodes
+ public override List ChildNodes
{
get
{
- IList childNodes = base.ChildNodes;
+ List childNodes = base.ChildNodes;
if (Document.Declaration != null && childNodes[0].NodeType != XmlNodeType.XmlDeclaration)
{
@@ -672,7 +682,7 @@ namespace Newtonsoft.Json.Converters
internal class XContainerWrapper : XObjectWrapper
{
- private IList _childNodes;
+ private List _childNodes;
private XContainer Container
{
@@ -684,7 +694,7 @@ namespace Newtonsoft.Json.Converters
{
}
- public override IList ChildNodes
+ public override List ChildNodes
{
get
{
@@ -692,7 +702,11 @@ namespace Newtonsoft.Json.Converters
// cache results to prevent multiple reads which kills perf in large documents
if (_childNodes == null)
{
- _childNodes = Container.Nodes().Select(WrapNode).ToList();
+ _childNodes = new List();
+ foreach (XNode node in Container.Nodes())
+ {
+ _childNodes.Add(WrapNode(node));
+ }
}
return _childNodes;
@@ -763,6 +777,7 @@ namespace Newtonsoft.Json.Converters
internal class XObjectWrapper : IXmlNode
{
+ private static readonly List EmptyChildNodes = new List();
private readonly XObject _xmlObject;
public XObjectWrapper(XObject xmlObject)
@@ -785,12 +800,12 @@ namespace Newtonsoft.Json.Converters
get { return null; }
}
- public virtual IList ChildNodes
+ public virtual List ChildNodes
{
- get { return new List(); }
+ get { return EmptyChildNodes; }
}
- public virtual IList Attributes
+ public virtual List Attributes
{
get { return null; }
}
@@ -861,6 +876,8 @@ namespace Newtonsoft.Json.Converters
internal class XElementWrapper : XContainerWrapper, IXmlElement
{
+ private List _attributes;
+
private XElement Element
{
get { return (XElement)WrappedNode; }
@@ -875,11 +892,56 @@ namespace Newtonsoft.Json.Converters
{
XObjectWrapper wrapper = (XObjectWrapper)attribute;
Element.Add(wrapper.WrappedNode);
+ _attributes = null;
}
- public override IList Attributes
+ public override List Attributes
{
- get { return Element.Attributes().Select(a => new XAttributeWrapper(a)).Cast().ToList(); }
+ get
+ {
+ // attributes is read multiple times
+ // cache results to prevent multiple reads which kills perf in large documents
+ if (_attributes == null)
+ {
+ _attributes = new List();
+ foreach (XAttribute attribute in Element.Attributes())
+ {
+ _attributes.Add(new XAttributeWrapper(attribute));
+ }
+
+ // ensure elements created with a namespace but no namespace attribute are converted correctly
+ // e.g. new XElement("{http://example.com}MyElement");
+ string namespaceUri = NamespaceUri;
+ if (!string.IsNullOrEmpty(namespaceUri) && namespaceUri != ParentNode?.NamespaceUri)
+ {
+ if (string.IsNullOrEmpty(GetPrefixOfNamespace(namespaceUri)))
+ {
+ bool namespaceDeclared = false;
+ foreach (IXmlNode attribute in _attributes)
+ {
+ if (attribute.LocalName == "xmlns" && string.IsNullOrEmpty(attribute.NamespaceUri) && attribute.Value == namespaceUri)
+ {
+ namespaceDeclared = true;
+ }
+ }
+
+ if (!namespaceDeclared)
+ {
+ _attributes.Insert(0, new XAttributeWrapper(new XAttribute("xmlns", namespaceUri)));
+ }
+ }
+ }
+ }
+
+ return _attributes;
+ }
+ }
+
+ public override IXmlNode AppendChild(IXmlNode newChild)
+ {
+ IXmlNode result = base.AppendChild(newChild);
+ _attributes = null;
+ return result;
}
public override string Value
@@ -1085,11 +1147,18 @@ namespace Newtonsoft.Json.Converters
private bool IsArray(IXmlNode node)
{
- IXmlNode jsonArrayAttribute = (node.Attributes != null)
- ? node.Attributes.SingleOrDefault(a => a.LocalName == "Array" && a.NamespaceUri == JsonNamespaceUri)
- : null;
+ if (node.Attributes != null)
+ {
+ foreach (IXmlNode attribute in node.Attributes)
+ {
+ if (attribute.LocalName == "Array" && attribute.NamespaceUri == JsonNamespaceUri)
+ {
+ return XmlConvert.ToBoolean(attribute.Value);
+ }
+ }
+ }
- return (jsonArrayAttribute != null && XmlConvert.ToBoolean(jsonArrayAttribute.Value));
+ return false;
}
private void SerializeGroupedNodes(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName)
@@ -1162,7 +1231,7 @@ namespace Newtonsoft.Json.Converters
SerializeGroupedNodes(writer, node, manager, writePropertyName);
break;
case XmlNodeType.Element:
- if (IsArray(node) && node.ChildNodes.All(n => n.LocalName == node.LocalName) && node.ChildNodes.Count > 0)
+ if (IsArray(node) && AllSameName(node) && node.ChildNodes.Count > 0)
{
SerializeGroupedNodes(writer, node, manager, false);
}
@@ -1188,7 +1257,7 @@ namespace Newtonsoft.Json.Converters
writer.WritePropertyName(GetPropertyName(node, manager));
}
- if (!ValueAttributes(node.Attributes).Any() && node.ChildNodes.Count == 1
+ if (!ValueAttributes(node.Attributes) && node.ChildNodes.Count == 1
&& node.ChildNodes[0].NodeType == XmlNodeType.Text)
{
// write elements with a single text child as a name value pair
@@ -1312,6 +1381,18 @@ namespace Newtonsoft.Json.Converters
throw new JsonSerializationException("Unexpected XmlNodeType when serializing nodes: " + node.NodeType);
}
}
+
+ private static bool AllSameName(IXmlNode node)
+ {
+ foreach (IXmlNode childNode in node.ChildNodes)
+ {
+ if (childNode.LocalName != node.LocalName)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
#endregion
#region Reading
@@ -1459,26 +1540,30 @@ namespace Newtonsoft.Json.Converters
string attributePrefix = MiscellaneousUtils.GetPrefix(attributeName);
AddAttribute(reader, document, currentNode, attributeName, manager, attributePrefix);
+ return;
}
- else if (propertyName.StartsWith('$'))
+
+ if (propertyName.StartsWith('$'))
{
- if (propertyName == JsonTypeReflector.ArrayValuesPropertyName)
+ switch (propertyName)
{
- propertyName = propertyName.Substring(1);
- elementPrefix = manager.LookupPrefix(JsonNamespaceUri);
- CreateElement(reader, document, currentNode, propertyName, manager, elementPrefix, attributeNameValues);
- }
- else
- {
- string attributeName = propertyName.Substring(1);
- string attributePrefix = manager.LookupPrefix(JsonNamespaceUri);
- AddAttribute(reader, document, currentNode, attributeName, manager, attributePrefix);
+ case JsonTypeReflector.ArrayValuesPropertyName:
+ propertyName = propertyName.Substring(1);
+ elementPrefix = manager.LookupPrefix(JsonNamespaceUri);
+ CreateElement(reader, document, currentNode, propertyName, manager, elementPrefix, attributeNameValues);
+ return;
+ case JsonTypeReflector.IdPropertyName:
+ case JsonTypeReflector.RefPropertyName:
+ case JsonTypeReflector.TypePropertyName:
+ case JsonTypeReflector.ValuePropertyName:
+ string attributeName = propertyName.Substring(1);
+ string attributePrefix = manager.LookupPrefix(JsonNamespaceUri);
+ AddAttribute(reader, document, currentNode, attributeName, manager, attributePrefix);
+ return;
}
}
- else
- {
- CreateElement(reader, document, currentNode, propertyName, manager, elementPrefix, attributeNameValues);
- }
+
+ CreateElement(reader, document, currentNode, propertyName, manager, elementPrefix, attributeNameValues);
}
private void CreateElement(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string elementName, XmlNamespaceManager manager, string elementPrefix, Dictionary attributeNameValues)
@@ -1624,8 +1709,15 @@ namespace Newtonsoft.Json.Converters
if (count == 1 && WriteArrayAttribute)
{
- IXmlElement arrayElement = nestedArrayElement.ChildNodes.OfType().Single(n => n.LocalName == propertyName);
- AddJsonArrayAttribute(arrayElement, document);
+ foreach (IXmlNode childNode in nestedArrayElement.ChildNodes)
+ {
+ IXmlElement element = childNode as IXmlElement;
+ if (element != null && element.LocalName == propertyName)
+ {
+ AddJsonArrayAttribute(element, document);
+ break;
+ }
+ }
}
}
@@ -1688,40 +1780,52 @@ namespace Newtonsoft.Json.Converters
}
break;
case '$':
- // check that JsonNamespaceUri is in scope
- // if it isn't then add it to document and namespace manager
- string jsonPrefix = manager.LookupPrefix(JsonNamespaceUri);
- if (jsonPrefix == null)
+ switch (attributeName)
{
- // ensure that the prefix used is free
- int? i = null;
- while (manager.LookupNamespace("json" + i) != null)
- {
- i = i.GetValueOrDefault() + 1;
- }
- jsonPrefix = "json" + i;
+ case JsonTypeReflector.ArrayValuesPropertyName:
+ case JsonTypeReflector.IdPropertyName:
+ case JsonTypeReflector.RefPropertyName:
+ case JsonTypeReflector.TypePropertyName:
+ case JsonTypeReflector.ValuePropertyName:
+ // check that JsonNamespaceUri is in scope
+ // if it isn't then add it to document and namespace manager
+ string jsonPrefix = manager.LookupPrefix(JsonNamespaceUri);
+ if (jsonPrefix == null)
+ {
+ // ensure that the prefix used is free
+ int? i = null;
+ while (manager.LookupNamespace("json" + i) != null)
+ {
+ i = i.GetValueOrDefault() + 1;
+ }
+ jsonPrefix = "json" + i;
- attributeNameValues.Add("xmlns:" + jsonPrefix, JsonNamespaceUri);
- manager.AddNamespace(jsonPrefix, JsonNamespaceUri);
+ attributeNameValues.Add("xmlns:" + jsonPrefix, JsonNamespaceUri);
+ manager.AddNamespace(jsonPrefix, JsonNamespaceUri);
+ }
+
+ // special case $values, it will have a non-primitive value
+ if (attributeName == JsonTypeReflector.ArrayValuesPropertyName)
+ {
+ finishedAttributes = true;
+ break;
+ }
+
+ attributeName = attributeName.Substring(1);
+ reader.Read();
+
+ if (!JsonTokenUtils.IsPrimitiveToken(reader.TokenType))
+ {
+ throw JsonSerializationException.Create(reader, "Unexpected JsonToken: " + reader.TokenType);
+ }
+
+ attributeValue = (reader.Value != null) ? reader.Value.ToString() : null;
+ attributeNameValues.Add(jsonPrefix + ":" + attributeName, attributeValue);
+ break;
+ default:
+ finishedAttributes = true;
+ break;
}
-
- // special case $values, it will have a non-primitive value
- if (attributeName == JsonTypeReflector.ArrayValuesPropertyName)
- {
- finishedAttributes = true;
- break;
- }
-
- attributeName = attributeName.Substring(1);
- reader.Read();
-
- if (!JsonTokenUtils.IsPrimitiveToken(reader.TokenType))
- {
- throw JsonSerializationException.Create(reader, "Unexpected JsonToken: " + reader.TokenType);
- }
-
- attributeValue = (reader.Value != null) ? reader.Value.ToString() : null;
- attributeNameValues.Add(jsonPrefix + ":" + attributeName, attributeValue);
break;
default:
finishedAttributes = true;
@@ -1858,8 +1962,15 @@ namespace Newtonsoft.Json.Converters
if (count == 1 && WriteArrayAttribute)
{
- IXmlElement arrayElement = currentNode.ChildNodes.OfType().Single(n => n.LocalName == propertyName);
- AddJsonArrayAttribute(arrayElement, document);
+ foreach (IXmlNode childNode in currentNode.ChildNodes)
+ {
+ IXmlElement element = childNode as IXmlElement;
+ if (element != null && element.LocalName == propertyName)
+ {
+ AddJsonArrayAttribute(element, document);
+ break;
+ }
+ }
}
}
else
@@ -1893,7 +2004,7 @@ namespace Newtonsoft.Json.Converters
///
/// Attribute name to test.
/// The attribute name prefix if it has one, otherwise an empty string.
- /// True if attribute name is for a namespace attribute, otherwise false.
+ /// true if attribute name is for a namespace attribute, otherwise false.
private bool IsNamespaceAttribute(string attributeName, out string prefix)
{
if (attributeName.StartsWith("xmlns", StringComparison.Ordinal))
@@ -1913,9 +2024,17 @@ namespace Newtonsoft.Json.Converters
return false;
}
- private IEnumerable ValueAttributes(IEnumerable c)
+ private bool ValueAttributes(List c)
{
- return c.Where(a => a.NamespaceUri != JsonNamespaceUri);
+ foreach (IXmlNode xmlNode in c)
+ {
+ if (xmlNode.NamespaceUri != JsonNamespaceUri)
+ {
+ return true;
+ }
+ }
+
+ return false;
}
#endregion
diff --git a/Src/Newtonsoft.Json/JsonReader.cs b/Src/Newtonsoft.Json/JsonReader.cs
index ce71c23e..4df922cb 100644
--- a/Src/Newtonsoft.Json/JsonReader.cs
+++ b/Src/Newtonsoft.Json/JsonReader.cs
@@ -407,7 +407,7 @@ namespace Newtonsoft.Json
///
/// Reads the next JSON token from the stream.
///
- /// true if the next token was read successfully; false if there are no more tokens to read.
+ /// true if the next token was read successfully; false if there are no more tokens to read.
public abstract bool Read();
///
@@ -622,12 +622,24 @@ namespace Newtonsoft.Json
case JsonToken.Float:
if (!(Value is double))
{
- SetToken(JsonToken.Float, Convert.ToDouble(Value, CultureInfo.InvariantCulture), false);
+ double d;
+#if !(NET20 || NET35 || PORTABLE40 || PORTABLE)
+ if (Value is BigInteger)
+ {
+ d = (double)(BigInteger)Value;
+ }
+ else
+#endif
+ {
+ d = Convert.ToDouble(Value, CultureInfo.InvariantCulture);
+ }
+
+ SetToken(JsonToken.Float, d, false);
}
- return (double) Value;
+ return (double)Value;
case JsonToken.String:
- return ReadDoubleString((string) Value);
+ return ReadDoubleString((string)Value);
}
throw JsonReaderException.Create(this, "Error reading double. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t));
diff --git a/Src/Newtonsoft.Json/JsonTextReader.cs b/Src/Newtonsoft.Json/JsonTextReader.cs
index 96a3ee83..cf2ca06b 100644
--- a/Src/Newtonsoft.Json/JsonTextReader.cs
+++ b/Src/Newtonsoft.Json/JsonTextReader.cs
@@ -362,7 +362,7 @@ namespace Newtonsoft.Json
/// Reads the next JSON token from the stream.
///
///
- /// true if the next token was read successfully; false if there are no more tokens to read.
+ /// true if the next token was read successfully; false if there are no more tokens to read.
///
public override bool Read()
{
@@ -598,6 +598,15 @@ namespace Newtonsoft.Json
throw new ArgumentOutOfRangeException(nameof(readType));
}
case '-':
+ if (EnsureChars(1, true) && _chars[_charPos + 1] == 'I')
+ {
+ return ParseNumberNegativeInfinity(readType);
+ }
+ else
+ {
+ ParseNumber(readType);
+ return Value;
+ }
case '.':
case '0':
case '1':
@@ -614,10 +623,8 @@ namespace Newtonsoft.Json
_charPos++;
throw CreateUnexpectedCharacterException(currentChar);
}
- ParseNumber(ReadType.Read);
- string s = ((IFormattable)Value).ToString(null, CultureInfo.InvariantCulture);
- SetToken(JsonToken.String, s);
- return s;
+ ParseNumber(ReadType.ReadAsString);
+ return Value;
case 't':
case 'f':
if (readType != ReadType.ReadAsString)
@@ -632,6 +639,10 @@ namespace Newtonsoft.Json
}
SetToken(JsonToken.String, expected);
return expected;
+ case 'I':
+ return ParseNumberPositiveInfinity(readType);
+ case 'N':
+ return ParseNumberNaN(readType);
case 'n':
HandleNull();
return null;
@@ -860,7 +871,20 @@ namespace Newtonsoft.Json
case 'n':
HandleNull();
return null;
+ case 'N':
+ return ParseNumberNaN(readType);
+ case 'I':
+ return ParseNumberPositiveInfinity(readType);
case '-':
+ if (EnsureChars(1, true) && _chars[_charPos + 1] == 'I')
+ {
+ return ParseNumberNegativeInfinity(readType);
+ }
+ else
+ {
+ ParseNumber(readType);
+ return Value;
+ }
case '.':
case '0':
case '1':
@@ -1569,15 +1593,15 @@ namespace Newtonsoft.Json
}
return true;
case 'N':
- ParseNumberNaN();
+ ParseNumberNaN(ReadType.Read);
return true;
case 'I':
- ParseNumberPositiveInfinity();
+ ParseNumberPositiveInfinity(ReadType.Read);
return true;
case '-':
if (EnsureChars(1, true) && _chars[_charPos + 1] == 'I')
{
- ParseNumberNegativeInfinity();
+ ParseNumberNegativeInfinity(ReadType.Read);
}
else
{
@@ -1807,7 +1831,42 @@ namespace Newtonsoft.Json
bool singleDigit = (char.IsDigit(firstChar) && _stringReference.Length == 1);
bool nonBase10 = (firstChar == '0' && _stringReference.Length > 1 && _stringReference.Chars[_stringReference.StartIndex + 1] != '.' && _stringReference.Chars[_stringReference.StartIndex + 1] != 'e' && _stringReference.Chars[_stringReference.StartIndex + 1] != 'E');
- if (readType == ReadType.ReadAsInt32)
+ if (readType == ReadType.ReadAsString)
+ {
+ string number = _stringReference.ToString();
+
+ // validate that the string is a valid number
+ if (nonBase10)
+ {
+ try
+ {
+ if (number.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
+ {
+ Convert.ToInt64(number, 16);
+ }
+ else
+ {
+ Convert.ToInt64(number, 8);
+ }
+ }
+ catch (Exception ex)
+ {
+ throw JsonReaderException.Create(this, "Input string '{0}' is not a valid number.".FormatWith(CultureInfo.InvariantCulture, number), ex);
+ }
+ }
+ else
+ {
+ double value;
+ if (!double.TryParse(number, NumberStyles.Float, CultureInfo.InvariantCulture, out value))
+ {
+ throw JsonReaderException.Create(this, "Input string '{0}' is not a valid number.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString()));
+ }
+ }
+
+ numberType = JsonToken.String;
+ numberValue = number;
+ }
+ else if (readType == ReadType.ReadAsInt32)
{
if (singleDigit)
{
@@ -2260,55 +2319,79 @@ namespace Newtonsoft.Json
}
}
- private void ParseNumberNegativeInfinity()
+ private object ParseNumberNegativeInfinity(ReadType readType)
{
if (MatchValueWithTrailingSeparator(JsonConvert.NegativeInfinity))
{
- if (_floatParseHandling == FloatParseHandling.Decimal)
+ switch (readType)
{
- throw new JsonReaderException("Cannot read -Infinity as a decimal.");
+ case ReadType.Read:
+ case ReadType.ReadAsDouble:
+ if (_floatParseHandling == FloatParseHandling.Double)
+ {
+ SetToken(JsonToken.Float, double.NegativeInfinity);
+ return double.NegativeInfinity;
+ }
+ break;
+ case ReadType.ReadAsString:
+ SetToken(JsonToken.String, JsonConvert.NegativeInfinity);
+ return JsonConvert.NegativeInfinity;
}
- SetToken(JsonToken.Float, double.NegativeInfinity);
- }
- else
- {
- throw JsonReaderException.Create(this, "Error parsing negative infinity value.");
+ throw JsonReaderException.Create(this, "Cannot read -Infinity value.");
}
+
+ throw JsonReaderException.Create(this, "Error parsing -Infinity value.");
}
- private void ParseNumberPositiveInfinity()
+ private object ParseNumberPositiveInfinity(ReadType readType)
{
if (MatchValueWithTrailingSeparator(JsonConvert.PositiveInfinity))
{
- if (_floatParseHandling == FloatParseHandling.Decimal)
+ switch (readType)
{
- throw new JsonReaderException("Cannot read Infinity as a decimal.");
+ case ReadType.Read:
+ case ReadType.ReadAsDouble:
+ if (_floatParseHandling == FloatParseHandling.Double)
+ {
+ SetToken(JsonToken.Float, double.PositiveInfinity);
+ return double.PositiveInfinity;
+ }
+ break;
+ case ReadType.ReadAsString:
+ SetToken(JsonToken.String, JsonConvert.PositiveInfinity);
+ return JsonConvert.PositiveInfinity;
}
- SetToken(JsonToken.Float, double.PositiveInfinity);
- }
- else
- {
- throw JsonReaderException.Create(this, "Error parsing positive infinity value.");
+ throw JsonReaderException.Create(this, "Cannot read Infinity value.");
}
+
+ throw JsonReaderException.Create(this, "Error parsing Infinity value.");
}
- private void ParseNumberNaN()
+ private object ParseNumberNaN(ReadType readType)
{
if (MatchValueWithTrailingSeparator(JsonConvert.NaN))
{
- if (_floatParseHandling == FloatParseHandling.Decimal)
+ switch (readType)
{
- throw new JsonReaderException("Cannot read NaN as a decimal.");
+ case ReadType.Read:
+ case ReadType.ReadAsDouble:
+ if (_floatParseHandling == FloatParseHandling.Double)
+ {
+ SetToken(JsonToken.Float, double.NaN);
+ return double.NaN;
+ }
+ break;
+ case ReadType.ReadAsString:
+ SetToken(JsonToken.String, JsonConvert.NaN);
+ return JsonConvert.NaN;
}
- SetToken(JsonToken.Float, double.NaN);
- }
- else
- {
- throw JsonReaderException.Create(this, "Error parsing NaN value.");
+ throw JsonReaderException.Create(this, "Cannot read NaN value.");
}
+
+ throw JsonReaderException.Create(this, "Error parsing NaN value.");
}
///
diff --git a/Src/Newtonsoft.Json/JsonValidatingReader.cs b/Src/Newtonsoft.Json/JsonValidatingReader.cs
index 260791b8..6e5d75a1 100644
--- a/Src/Newtonsoft.Json/JsonValidatingReader.cs
+++ b/Src/Newtonsoft.Json/JsonValidatingReader.cs
@@ -495,7 +495,7 @@ namespace Newtonsoft.Json
/// Reads the next JSON token from the stream.
///
///
- /// true if the next token was read successfully; false if there are no more tokens to read.
+ /// true if the next token was read successfully; false if there are no more tokens to read.
///
public override bool Read()
{
diff --git a/Src/Newtonsoft.Json/JsonWriter.cs b/Src/Newtonsoft.Json/JsonWriter.cs
index 293b1536..40fa2bce 100644
--- a/Src/Newtonsoft.Json/JsonWriter.cs
+++ b/Src/Newtonsoft.Json/JsonWriter.cs
@@ -626,7 +626,7 @@ namespace Newtonsoft.Json
WriteToken(token, null);
}
- internal void WriteToken(JsonReader reader, bool writeChildren, bool writeDateConstructorAsDate, bool writeComments)
+ internal virtual void WriteToken(JsonReader reader, bool writeChildren, bool writeDateConstructorAsDate, bool writeComments)
{
int initialDepth;
@@ -643,11 +643,6 @@ namespace Newtonsoft.Json
initialDepth = reader.Depth;
}
- WriteToken(reader, initialDepth, writeChildren, writeDateConstructorAsDate, writeComments);
- }
-
- internal void WriteToken(JsonReader reader, int initialDepth, bool writeChildren, bool writeDateConstructorAsDate, bool writeComments)
- {
do
{
// write a JValue date when the constructor is for a date
@@ -657,7 +652,7 @@ namespace Newtonsoft.Json
}
else
{
- if (reader.TokenType != JsonToken.Comment || writeComments)
+ if (writeComments || reader.TokenType != JsonToken.Comment)
{
WriteToken(reader.TokenType, reader.Value);
}
diff --git a/Src/Newtonsoft.Json/Linq/JArray.cs b/Src/Newtonsoft.Json/Linq/JArray.cs
index 5ca9a165..ad73e028 100644
--- a/Src/Newtonsoft.Json/Linq/JArray.cs
+++ b/Src/Newtonsoft.Json/Linq/JArray.cs
@@ -270,6 +270,11 @@ namespace Newtonsoft.Json.Linq
set { SetItem(index, value); }
}
+ internal override int IndexOfItem(JToken item)
+ {
+ return _values.IndexOfReference(item);
+ }
+
internal override void MergeItem(object content, JsonMergeSettings settings)
{
IEnumerable a = (IsMultiContent(content) || content is JArray)
diff --git a/Src/Newtonsoft.Json/Linq/JConstructor.cs b/Src/Newtonsoft.Json/Linq/JConstructor.cs
index 0a49a93e..1411caf6 100644
--- a/Src/Newtonsoft.Json/Linq/JConstructor.cs
+++ b/Src/Newtonsoft.Json/Linq/JConstructor.cs
@@ -48,6 +48,11 @@ namespace Newtonsoft.Json.Linq
get { return _values; }
}
+ internal override int IndexOfItem(JToken item)
+ {
+ return _values.IndexOfReference(item);
+ }
+
internal override void MergeItem(object content, JsonMergeSettings settings)
{
JConstructor c = content as JConstructor;
diff --git a/Src/Newtonsoft.Json/Linq/JContainer.cs b/Src/Newtonsoft.Json/Linq/JContainer.cs
index 6e902010..0ad8a5ce 100644
--- a/Src/Newtonsoft.Json/Linq/JContainer.cs
+++ b/Src/Newtonsoft.Json/Linq/JContainer.cs
@@ -351,30 +351,7 @@ namespace Newtonsoft.Json.Linq
return item;
}
- private class JTokenReferenceEqualityComparer : IEqualityComparer
- {
- public static readonly JTokenReferenceEqualityComparer Instance = new JTokenReferenceEqualityComparer();
-
- public bool Equals(JToken x, JToken y)
- {
- return ReferenceEquals(x, y);
- }
-
- public int GetHashCode(JToken obj)
- {
- if (obj == null)
- {
- return 0;
- }
-
- return obj.GetHashCode();
- }
- }
-
- internal int IndexOfItem(JToken item)
- {
- return ChildrenTokens.IndexOf(item, JTokenReferenceEqualityComparer.Instance);
- }
+ internal abstract int IndexOfItem(JToken item);
internal virtual void InsertItem(int index, JToken item, bool skipParentCheck)
{
@@ -698,9 +675,10 @@ namespace Newtonsoft.Json.Linq
internal static JToken CreateFromContent(object content)
{
- if (content is JToken)
+ JToken token = content as JToken;
+ if (token != null)
{
- return (JToken)content;
+ return token;
}
return new JValue(content);
@@ -782,7 +760,7 @@ namespace Newtonsoft.Json.Linq
do
{
- if (parent is JProperty && ((JProperty)parent).Value != null)
+ if ((parent as JProperty)?.Value != null)
{
if (parent == this)
{
@@ -910,12 +888,7 @@ namespace Newtonsoft.Json.Linq
PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors)
{
ICustomTypeDescriptor d = First as ICustomTypeDescriptor;
- if (d != null)
- {
- return d.GetProperties();
- }
-
- return null;
+ return d?.GetProperties();
}
#endif
@@ -981,9 +954,10 @@ namespace Newtonsoft.Json.Linq
return null;
}
- if (value is JToken)
+ JToken token = value as JToken;
+ if (token != null)
{
- return (JToken)value;
+ return token;
}
throw new ArgumentException("Argument is not a JToken.");
@@ -1192,7 +1166,7 @@ namespace Newtonsoft.Json.Linq
}
}
#else
- IDictionary items = new Dictionary(EqualityComparer);
+ Dictionary items = new Dictionary(EqualityComparer);
foreach (JToken t in target)
{
items[t] = true;
diff --git a/Src/Newtonsoft.Json/Linq/JObject.cs b/Src/Newtonsoft.Json/Linq/JObject.cs
index 7e7d49c1..45c21403 100644
--- a/Src/Newtonsoft.Json/Linq/JObject.cs
+++ b/Src/Newtonsoft.Json/Linq/JObject.cs
@@ -128,6 +128,11 @@ namespace Newtonsoft.Json.Linq
return _properties.Compare(t._properties);
}
+ internal override int IndexOfItem(JToken item)
+ {
+ return _properties.IndexOfReference(item);
+ }
+
internal override void InsertItem(int index, JToken item, bool skipParentCheck)
{
// don't add comments to JObject, no name to reference comment by
@@ -523,7 +528,7 @@ namespace Newtonsoft.Json.Linq
/// Name of the property.
/// The value.
/// One of the enumeration values that specifies how the strings will be compared.
- /// true if a value was successfully retrieved; otherwise, false.
+ /// true if a value was successfully retrieved; otherwise, false.
public bool TryGetValue(string propertyName, StringComparison comparison, out JToken value)
{
value = GetValue(propertyName, comparison);
@@ -556,7 +561,7 @@ namespace Newtonsoft.Json.Linq
/// Removes the property with the specified name.
///
/// Name of the property.
- /// true if item was successfully removed; otherwise, false.
+ /// true if item was successfully removed; otherwise, false.
public bool Remove(string propertyName)
{
JProperty property = Property(propertyName);
@@ -574,7 +579,7 @@ namespace Newtonsoft.Json.Linq
///
/// Name of the property.
/// The value.
- /// true if a value was successfully retrieved; otherwise, false.
+ /// true if a value was successfully retrieved; otherwise, false.
public bool TryGetValue(string propertyName, out JToken value)
{
JProperty property = Property(propertyName);
diff --git a/Src/Newtonsoft.Json/Linq/JProperty.cs b/Src/Newtonsoft.Json/Linq/JProperty.cs
index a1049cf0..c68502a0 100644
--- a/Src/Newtonsoft.Json/Linq/JProperty.cs
+++ b/Src/Newtonsoft.Json/Linq/JProperty.cs
@@ -235,6 +235,11 @@ namespace Newtonsoft.Json.Linq
throw new JsonException("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
}
+ internal override int IndexOfItem(JToken item)
+ {
+ return _content.IndexOf(item);
+ }
+
internal override void InsertItem(int index, JToken item, bool skipParentCheck)
{
// don't add comments to JProperty
diff --git a/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs b/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs
index 00eb8575..0b7b34eb 100644
--- a/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs
+++ b/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs
@@ -52,10 +52,9 @@ namespace Newtonsoft.Json.Linq
/// When overridden in a derived class, returns whether resetting an object changes its value.
///
///
- /// true if resetting the component changes its value; otherwise, false.
+ /// true if resetting the component changes its value; otherwise, false.
///
- /// The component to test for reset capability.
- ///
+ /// The component to test for reset capability.
public override bool CanResetValue(object component)
{
return false;
@@ -102,10 +101,9 @@ namespace Newtonsoft.Json.Linq
/// When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted.
///
///
- /// true if the property should be persisted; otherwise, false.
+ /// true if the property should be persisted; otherwise, false.
///
- /// The component with the property to be examined for persistence.
- ///
+ /// The component with the property to be examined for persistence.
public override bool ShouldSerializeValue(object component)
{
return false;
@@ -126,7 +124,7 @@ namespace Newtonsoft.Json.Linq
/// When overridden in a derived class, gets a value indicating whether this property is read-only.
///
///
- /// true if the property is read-only; otherwise, false.
+ /// true if the property is read-only; otherwise, false.
///
public override bool IsReadOnly
{
diff --git a/Src/Newtonsoft.Json/Linq/JPropertyKeyedCollection.cs b/Src/Newtonsoft.Json/Linq/JPropertyKeyedCollection.cs
index 867d741c..527fdab5 100644
--- a/Src/Newtonsoft.Json/Linq/JPropertyKeyedCollection.cs
+++ b/Src/Newtonsoft.Json/Linq/JPropertyKeyedCollection.cs
@@ -26,6 +26,7 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Linq
{
@@ -35,6 +36,10 @@ namespace Newtonsoft.Json.Linq
private Dictionary _dictionary;
+ public JPropertyKeyedCollection() : base(new List())
+ {
+ }
+
private void AddKey(string key, JToken item)
{
EnsureDictionary();
@@ -220,6 +225,11 @@ namespace Newtonsoft.Json.Linq
}
}
+ public int IndexOfReference(JToken t)
+ {
+ return ((List)Items).IndexOfReference(t);
+ }
+
public bool Compare(JPropertyKeyedCollection other)
{
if (this == other)
diff --git a/Src/Newtonsoft.Json/Linq/JToken.cs b/Src/Newtonsoft.Json/Linq/JToken.cs
index 7a162847..8bcbf83d 100644
--- a/Src/Newtonsoft.Json/Linq/JToken.cs
+++ b/Src/Newtonsoft.Json/Linq/JToken.cs
@@ -152,7 +152,7 @@ namespace Newtonsoft.Json.Linq
///
/// The first to compare.
/// The second to compare.
- /// true if the tokens are equal; otherwise false.
+ /// true if the tokens are equal; otherwise false.
public static bool DeepEquals(JToken t1, JToken t2)
{
return (t1 == t2 || (t1 != null && t2 != null && t1.DeepEquals(t2)));
@@ -190,40 +190,32 @@ namespace Newtonsoft.Json.Linq
return string.Empty;
}
- IList ancestors = AncestorsAndSelf().Reverse().ToList();
-
List positions = new List();
- for (int i = 0; i < ancestors.Count; i++)
+ JToken previous = null;
+ for (JToken current = this; current != null; current = current.Parent)
{
- JToken current = ancestors[i];
- JToken next = null;
- if (i + 1 < ancestors.Count)
+ switch (current.Type)
{
- next = ancestors[i + 1];
- }
- else if (ancestors[i].Type == JTokenType.Property)
- {
- next = ancestors[i];
- }
-
- if (next != null)
- {
- switch (current.Type)
- {
- case JTokenType.Property:
- JProperty property = (JProperty)current;
- positions.Add(new JsonPosition(JsonContainerType.Object) { PropertyName = property.Name });
- break;
- case JTokenType.Array:
- case JTokenType.Constructor:
- int index = ((IList)current).IndexOf(next);
+ case JTokenType.Property:
+ JProperty property = (JProperty)current;
+ positions.Add(new JsonPosition(JsonContainerType.Object) { PropertyName = property.Name });
+ break;
+ case JTokenType.Array:
+ case JTokenType.Constructor:
+ if (previous != null)
+ {
+ int index = ((IList)current).IndexOf(previous);
positions.Add(new JsonPosition(JsonContainerType.Array) { Position = index });
- break;
- }
+ }
+ break;
}
+
+ previous = current;
}
+ positions.Reverse();
+
return JsonPosition.BuildPath(positions, null);
}
}
@@ -1883,7 +1875,7 @@ namespace Newtonsoft.Json.Linq
/// An that can be used to read this token and its descendants.
public JsonReader CreateReader()
{
- return new JTokenReader(this, Path);
+ return new JTokenReader(this);
}
internal static JToken FromObjectInternal(object o, JsonSerializer jsonSerializer)
diff --git a/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs b/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs
index fd10537a..33dd3f13 100644
--- a/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs
+++ b/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs
@@ -38,7 +38,7 @@ namespace Newtonsoft.Json.Linq
/// The first object of type to compare.
/// The second object of type to compare.
///
- /// true if the specified objects are equal; otherwise, false.
+ /// true if the specified objects are equal; otherwise, false.
///
public bool Equals(JToken x, JToken y)
{
diff --git a/Src/Newtonsoft.Json/Linq/JTokenReader.cs b/Src/Newtonsoft.Json/Linq/JTokenReader.cs
index 5f0ca876..0f5c98dc 100644
--- a/Src/Newtonsoft.Json/Linq/JTokenReader.cs
+++ b/Src/Newtonsoft.Json/Linq/JTokenReader.cs
@@ -33,8 +33,8 @@ namespace Newtonsoft.Json.Linq
///
public class JTokenReader : JsonReader, IJsonLineInfo
{
- private readonly string _initialPath;
private readonly JToken _root;
+ private string _initialPath;
private JToken _parent;
private JToken _current;
@@ -57,6 +57,7 @@ namespace Newtonsoft.Json.Linq
_root = token;
}
+ // this is used by json.net schema
internal JTokenReader(JToken token, string initialPath)
: this(token)
{
@@ -67,7 +68,7 @@ namespace Newtonsoft.Json.Linq
/// Reads the next JSON token from the stream.
///
///
- /// true if the next token was read successfully; false if there are no more tokens to read.
+ /// true if the next token was read successfully; false if there are no more tokens to read.
///
public override bool Read()
{
@@ -306,6 +307,11 @@ namespace Newtonsoft.Json.Linq
{
string path = base.Path;
+ if (_initialPath == null)
+ {
+ _initialPath = _root.Path;
+ }
+
if (!string.IsNullOrEmpty(_initialPath))
{
if (string.IsNullOrEmpty(path))
diff --git a/Src/Newtonsoft.Json/Linq/JTokenWriter.cs b/Src/Newtonsoft.Json/Linq/JTokenWriter.cs
index 03318509..86e5d954 100644
--- a/Src/Newtonsoft.Json/Linq/JTokenWriter.cs
+++ b/Src/Newtonsoft.Json/Linq/JTokenWriter.cs
@@ -485,5 +485,53 @@ namespace Newtonsoft.Json.Linq
AddValue(value, JsonToken.String);
}
#endregion
+
+ internal override void WriteToken(JsonReader reader, bool writeChildren, bool writeDateConstructorAsDate, bool writeComments)
+ {
+ JTokenReader tokenReader = reader as JTokenReader;
+
+ // closing the token wrather than reading then writing it doesn't lose some type information, e.g. Guid, byte[], etc
+ if (tokenReader != null && writeChildren && writeDateConstructorAsDate && writeComments)
+ {
+ if (tokenReader.TokenType == JsonToken.None)
+ {
+ if (!tokenReader.Read())
+ {
+ return;
+ }
+ }
+
+ JToken value = tokenReader.CurrentToken.CloneToken();
+
+ if (_parent != null)
+ {
+ _parent.Add(value);
+ _current = _parent.Last;
+
+ // if the writer was in a property then move out of it and up to its parent object
+ if (_parent.Type == JTokenType.Property)
+ {
+ _parent = _parent.Parent;
+ InternalWriteValue(JsonToken.Null);
+ }
+ }
+ else
+ {
+ _current = value;
+
+ if (_token == null && _value == null)
+ {
+ _token = value as JContainer;
+ _value = value as JValue;
+ }
+ }
+
+ tokenReader.Skip();
+ }
+ else
+ {
+ base.WriteToken(reader, writeChildren, writeDateConstructorAsDate, writeComments);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Linq/JValue.cs b/Src/Newtonsoft.Json/Linq/JValue.cs
index 8dd1297e..d6d6b30e 100644
--- a/Src/Newtonsoft.Json/Linq/JValue.cs
+++ b/Src/Newtonsoft.Json/Linq/JValue.cs
@@ -819,11 +819,13 @@ namespace Newtonsoft.Json.Linq
writer.WriteValue((byte[])_value);
return;
case JTokenType.Guid:
+ writer.WriteValue((_value != null) ? (Guid?)_value : null);
+ return;
case JTokenType.TimeSpan:
- writer.WriteValue((_value != null) ? _value.ToString() : null);
+ writer.WriteValue((_value != null) ? (TimeSpan?)_value : null);
return;
case JTokenType.Uri:
- writer.WriteValue((_value != null) ? ((Uri)_value).OriginalString : null);
+ writer.WriteValue((Uri)_value);
return;
}
@@ -847,7 +849,7 @@ namespace Newtonsoft.Json.Linq
/// Indicates whether the current object is equal to another object of the same type.
///
///
- /// true if the current object is equal to the parameter; otherwise, false.
+ /// true if the current object is equal to the parameter; otherwise, false.
///
/// An object to compare with this object.
public bool Equals(JValue other)
@@ -865,7 +867,7 @@ namespace Newtonsoft.Json.Linq
///
/// The to compare with the current .
///
- /// true if the specified is equal to the current ; otherwise, false.
+ /// true if the specified is equal to the current ; otherwise, false.
///
///
/// The parameter is null.
diff --git a/Src/Newtonsoft.Json/Linq/JsonPath/QueryExpression.cs b/Src/Newtonsoft.Json/Linq/JsonPath/QueryExpression.cs
index 3b5c44e4..ee80d779 100644
--- a/Src/Newtonsoft.Json/Linq/JsonPath/QueryExpression.cs
+++ b/Src/Newtonsoft.Json/Linq/JsonPath/QueryExpression.cs
@@ -76,48 +76,60 @@ namespace Newtonsoft.Json.Linq.JsonPath
foreach (JToken r in pathResult)
{
JValue v = r as JValue;
- switch (Operator)
+ if (v != null)
{
- case QueryOperator.Equals:
- if (v != null && EqualsWithStringCoercion(v, Value))
- {
+ switch (Operator)
+ {
+ case QueryOperator.Equals:
+ if (EqualsWithStringCoercion(v, Value))
+ {
+ return true;
+ }
+ break;
+ case QueryOperator.NotEquals:
+ if (!EqualsWithStringCoercion(v, Value))
+ {
+ return true;
+ }
+ break;
+ case QueryOperator.GreaterThan:
+ if (v.CompareTo(Value) > 0)
+ {
+ return true;
+ }
+ break;
+ case QueryOperator.GreaterThanOrEquals:
+ if (v.CompareTo(Value) >= 0)
+ {
+ return true;
+ }
+ break;
+ case QueryOperator.LessThan:
+ if (v.CompareTo(Value) < 0)
+ {
+ return true;
+ }
+ break;
+ case QueryOperator.LessThanOrEquals:
+ if (v.CompareTo(Value) <= 0)
+ {
+ return true;
+ }
+ break;
+ case QueryOperator.Exists:
return true;
- }
- break;
- case QueryOperator.NotEquals:
- if (v != null && !EqualsWithStringCoercion(v, Value))
- {
+ }
+ }
+ else
+ {
+ switch (Operator)
+ {
+ case QueryOperator.Exists:
+ // you can only specify primative types in a comparison
+ // notequals will always be true
+ case QueryOperator.NotEquals:
return true;
- }
- break;
- case QueryOperator.GreaterThan:
- if (v != null && v.CompareTo(Value) > 0)
- {
- return true;
- }
- break;
- case QueryOperator.GreaterThanOrEquals:
- if (v != null && v.CompareTo(Value) >= 0)
- {
- return true;
- }
- break;
- case QueryOperator.LessThan:
- if (v != null && v.CompareTo(Value) < 0)
- {
- return true;
- }
- break;
- case QueryOperator.LessThanOrEquals:
- if (v != null && v.CompareTo(Value) <= 0)
- {
- return true;
- }
- break;
- case QueryOperator.Exists:
- return true;
- default:
- throw new ArgumentOutOfRangeException();
+ }
}
}
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Dotnet.xproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Dotnet.xproj
index c841f384..07d8d0ba 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Dotnet.xproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Dotnet.xproj
@@ -9,9 +9,8 @@
779e052e-7218-4da3-b419-ffb0f4c95081
Newtonsoft.Json
..\artifacts\obj\$(MSBuildProjectName)
- ..\artifacts\bin\$(MSBuildProjectName)\
+ .\bin\
-
2.0
diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
index bfc61ab8..62cc370e 100644
--- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
+++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
@@ -32,7 +32,9 @@ using System.Security;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-#if PORTABLE40
+#if NETSTANDARD10
+[assembly: AssemblyTitle("Json.NET .NET Standard 1.0")]
+#elif PORTABLE40
[assembly: AssemblyTitle("Json.NET Portable .NET 4.0")]
#elif PORTABLE
[assembly: AssemblyTitle("Json.NET Portable")]
@@ -48,7 +50,6 @@ using System.Security;
[assembly: AssemblyTitle("Json.NET .NET 4.0")]
[assembly: AllowPartiallyTrustedCallers]
#else
-
[assembly: AssemblyTitle("Json.NET")]
[assembly: AllowPartiallyTrustedCallers]
#endif
diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
index 3c0b769e..199f925b 100644
--- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
+++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
@@ -40,7 +40,6 @@ using System.Runtime.Serialization;
#if !(DOTNET || PORTABLE || PORTABLE40)
using System.Security.Permissions;
#endif
-using System.Xml.Serialization;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Utilities;
using Newtonsoft.Json.Linq;
diff --git a/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs b/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
index ab3829c5..ab566543 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
@@ -172,7 +172,10 @@ namespace Newtonsoft.Json.Serialization
if (keyType != null && valueType != null)
{
- _parameterizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(CreatedType, typeof(KeyValuePair<,>).MakeGenericType(keyType, valueType));
+ _parameterizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(
+ CreatedType,
+ typeof(KeyValuePair<,>).MakeGenericType(keyType, valueType),
+ typeof(IDictionary<,>).MakeGenericType(keyType, valueType));
#if !(NET35 || NET20)
if (!HasParameterizedCreatorInternal && underlyingType.Name == FSharpUtils.FSharpMapTypeName)
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
index 7864da5c..ff1be4c8 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
@@ -2041,9 +2041,19 @@ namespace Newtonsoft.Json.Serialization
IDictionary targetDictionary = (dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(createdObjectDictionary) : (IDictionary)createdObjectDictionary;
IDictionary newValues = (dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(value) : (IDictionary)value;
- foreach (DictionaryEntry newValue in newValues)
+ // Manual use of IDictionaryEnumerator instead of foreach to avoid DictionaryEntry box allocations.
+ IDictionaryEnumerator e = newValues.GetEnumerator();
+ try
{
- targetDictionary.Add(newValue.Key, newValue.Value);
+ while (e.MoveNext())
+ {
+ DictionaryEntry entry = e.Entry;
+ targetDictionary.Add(entry.Key, entry.Value);
+ }
+ }
+ finally
+ {
+ (e as IDisposable)?.Dispose();
}
}
}
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
index d5b84963..6f2679e9 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
@@ -1050,49 +1050,60 @@ namespace Newtonsoft.Json.Serialization
int initialDepth = writer.Top;
- foreach (DictionaryEntry entry in values)
+ // Manual use of IDictionaryEnumerator instead of foreach to avoid DictionaryEntry box allocations.
+ IDictionaryEnumerator e = values.GetEnumerator();
+ try
{
- bool escape;
- string propertyName = GetPropertyName(writer, entry.Key, contract.KeyContract, out escape);
-
- propertyName = (contract.DictionaryKeyResolver != null)
- ? contract.DictionaryKeyResolver(propertyName)
- : propertyName;
-
- try
+ while (e.MoveNext())
{
- object value = entry.Value;
- JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);
+ DictionaryEntry entry = e.Entry;
- if (ShouldWriteReference(value, null, valueContract, contract, member))
+ bool escape;
+ string propertyName = GetPropertyName(writer, entry.Key, contract.KeyContract, out escape);
+
+ propertyName = (contract.DictionaryKeyResolver != null)
+ ? contract.DictionaryKeyResolver(propertyName)
+ : propertyName;
+
+ try
{
- writer.WritePropertyName(propertyName, escape);
- WriteReference(writer, value);
- }
- else
- {
- if (!CheckForCircularReference(writer, value, null, valueContract, contract, member))
+ object value = entry.Value;
+ JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);
+
+ if (ShouldWriteReference(value, null, valueContract, contract, member))
{
- continue;
+ writer.WritePropertyName(propertyName, escape);
+ WriteReference(writer, value);
}
+ else
+ {
+ if (!CheckForCircularReference(writer, value, null, valueContract, contract, member))
+ {
+ continue;
+ }
- writer.WritePropertyName(propertyName, escape);
+ writer.WritePropertyName(propertyName, escape);
- SerializeValue(writer, value, valueContract, null, contract, member);
+ SerializeValue(writer, value, valueContract, null, contract, member);
+ }
}
- }
- catch (Exception ex)
- {
- if (IsErrorHandled(underlyingDictionary, contract, propertyName, null, writer.ContainerPath, ex))
+ catch (Exception ex)
{
- HandleError(writer, initialDepth);
- }
- else
- {
- throw;
+ if (IsErrorHandled(underlyingDictionary, contract, propertyName, null, writer.ContainerPath, ex))
+ {
+ HandleError(writer, initialDepth);
+ }
+ else
+ {
+ throw;
+ }
}
}
}
+ finally
+ {
+ (e as IDisposable)?.Dispose();
+ }
writer.WriteEndObject();
diff --git a/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs b/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs
index 6b84fc34..bd504720 100644
--- a/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs
+++ b/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs
@@ -113,6 +113,13 @@ namespace Newtonsoft.Json.Utilities
}
public static ConstructorInfo ResolveEnumerableCollectionConstructor(Type collectionType, Type collectionItemType)
+ {
+ Type genericConstructorArgument = typeof(IList<>).MakeGenericType(collectionItemType);
+
+ return ResolveEnumerableCollectionConstructor(collectionType, collectionItemType, genericConstructorArgument);
+ }
+
+ public static ConstructorInfo ResolveEnumerableCollectionConstructor(Type collectionType, Type collectionItemType, Type constructorArgumentType)
{
Type genericEnumerable = typeof(IEnumerable<>).MakeGenericType(collectionItemType);
ConstructorInfo match = null;
@@ -123,7 +130,9 @@ namespace Newtonsoft.Json.Utilities
if (parameters.Count == 1)
{
- if (genericEnumerable == parameters[0].ParameterType)
+ Type parameterType = parameters[0].ParameterType;
+
+ if (genericEnumerable == parameterType)
{
// exact match
match = constructor;
@@ -133,7 +142,7 @@ namespace Newtonsoft.Json.Utilities
// incase we can't find an exact match, use first inexact
if (match == null)
{
- if (genericEnumerable.IsAssignableFrom(parameters[0].ParameterType))
+ if (parameterType.IsAssignableFrom(constructorArgumentType))
{
match = constructor;
}
@@ -214,11 +223,11 @@ namespace Newtonsoft.Json.Utilities
return -1;
}
- public static bool Contains(this IEnumerable list, object value, IEqualityComparer comparer)
+ public static bool Contains(this List list, T value, IEqualityComparer comparer)
{
- foreach (object item in list)
+ for (int i = 0; i < list.Count; i++)
{
- if (comparer.Equals(item, value))
+ if (comparer.Equals(value, list[i]))
{
return true;
}
@@ -226,24 +235,14 @@ namespace Newtonsoft.Json.Utilities
return false;
}
- ///
- /// Returns the index of the first occurrence in a sequence by using a specified IEqualityComparer{TSource}.
- ///
- /// The type of the elements of source.
- /// A sequence in which to locate a value.
- /// The object to locate in the sequence
- /// An equality comparer to compare values.
- /// The zero-based index of the first occurrence of value within the entire sequence, if found; otherwise, –1.
- public static int IndexOf(this IEnumerable list, TSource value, IEqualityComparer comparer)
+ public static int IndexOfReference(this List list, T item)
{
- int index = 0;
- foreach (TSource item in list)
+ for (int i = 0; i < list.Count; i++)
{
- if (comparer.Equals(item, value))
+ if (ReferenceEquals(item, list[i]))
{
- return index;
+ return i;
}
- index++;
}
return -1;
}
diff --git a/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs b/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs
index 4819c23d..4208513a 100644
--- a/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs
+++ b/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs
@@ -299,9 +299,19 @@ namespace Newtonsoft.Json.Utilities
{
if (_dictionary != null)
{
- foreach (DictionaryEntry item in _dictionary)
+ // Manual use of IDictionaryEnumerator instead of foreach to avoid DictionaryEntry box allocations.
+ IDictionaryEnumerator e = _dictionary.GetEnumerator();
+ try
{
- array[arrayIndex++] = new KeyValuePair((TKey)item.Key, (TValue)item.Value);
+ while (e.MoveNext())
+ {
+ DictionaryEntry entry = e.Entry;
+ array[arrayIndex++] = new KeyValuePair((TKey)entry.Key, (TValue)entry.Value);
+ }
+ }
+ finally
+ {
+ (e as IDisposable)?.Dispose();
}
}
#if !(NET40 || NET35 || NET20 || PORTABLE40)
diff --git a/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs b/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs
index 13cfe7b0..fdd930b5 100644
--- a/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs
+++ b/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs
@@ -240,7 +240,7 @@ namespace Newtonsoft.Json.Utilities
public override Func CreateGet(PropertyInfo propertyInfo)
{
- DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + propertyInfo.Name, typeof(T), new[] { typeof(object) }, propertyInfo.DeclaringType);
+ DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + propertyInfo.Name, typeof(object), new[] { typeof(T) }, propertyInfo.DeclaringType);
ILGenerator generator = dynamicMethod.GetILGenerator();
GenerateCreateGetPropertyIL(propertyInfo, generator);
diff --git a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
index ba79efca..382d8b02 100644
--- a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
+++ b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
@@ -769,9 +769,11 @@ namespace Newtonsoft.Json.Utilities
Attribute[] attributes = a.Cast().ToArray();
#if (NET20 || NET35)
- // ye olde .NET GetCustomAttributes doesn't respect the inherit argument
+ // ye olde .NET GetCustomAttributes doesn't respect the inherit argument
if (inherit && t.BaseType != null)
+ {
attributes = attributes.Union(GetAttributes(t.BaseType, attributeType, inherit)).ToArray();
+ }
#endif
return attributes;
diff --git a/Src/Newtonsoft.Json/project.json b/Src/Newtonsoft.Json/project.json
index 2b461622..e8b2eb0f 100644
--- a/Src/Newtonsoft.Json/project.json
+++ b/Src/Newtonsoft.Json/project.json
@@ -1,14 +1,19 @@
{
- "version": "7.0.2-beta1",
+ "version": "1.0.0-*",
"title": "Json.NET",
"description": "Json.NET is a popular high-performance JSON framework for .NET",
- "authors": [ "James Newton-King" ],
- "tags": [ "json" ],
- "projectUrl": "http://www.newtonsoft.com/json",
- "licenseUrl": "https://raw.github.com/JamesNK/Newtonsoft.Json/master/LICENSE.md",
- "iconUrl": "http://www.newtonsoft.com/content/images/nugeticon.png",
"language": "en-US",
-
+ "authors": [ "James Newton-King" ],
+ "packOptions": {
+ "projectUrl": "http://www.newtonsoft.com/json",
+ "tags": [ "json" ],
+ "licenseUrl": "https://raw.github.com/JamesNK/Newtonsoft.Json/master/LICENSE.md",
+ "iconUrl": "http://www.newtonsoft.com/content/images/nugeticon.png",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/JamesNK/Newtonsoft.Json"
+ }
+ },
"frameworks": {
"net45": {
"frameworkAssemblies": {
@@ -44,8 +49,10 @@
}
},
".NETPortable,Version=v4.5,Profile=Profile259": {
- "compilationOptions": {
- "define": [ "PORTABLE" ]
+ "buildOptions": {
+ "define": [
+ "PORTABLE"
+ ]
},
"frameworkAssemblies": {
"Microsoft.CSharp": "",
@@ -61,6 +68,7 @@
"System.ObjectModel": "",
"System.Reflection": "",
"System.Reflection.Extensions": "",
+ "System.Resources.ResourceManager": "",
"System.Runtime": "",
"System.Runtime.Extensions": "",
"System.Runtime.Serialization": "",
@@ -77,8 +85,10 @@
}
},
".NETPortable,Version=v4.0,Profile=Profile328": {
- "compilationOptions": {
- "define": [ "PORTABLE40" ]
+ "buildOptions": {
+ "define": [
+ "PORTABLE40"
+ ]
},
"frameworkAssemblies": {
"mscorlib": "",
@@ -88,32 +98,36 @@
"System.Xml": ""
}
},
- "dotnet": {
+ "netstandard1.0": {
+ "buildOptions": {
+ "define": [
+ "NETSTANDARD10",
+ "PORTABLE"
+ ]
+ },
"dependencies": {
- "Microsoft.CSharp": "4.0.0",
- "System.Collections": "4.0.10",
- "System.Collections.Concurrent": "4.0.10",
- "System.ComponentModel.TypeConverter": "4.0.0",
- "System.Diagnostics.Debug": "4.0.10",
- "System.Dynamic.Runtime": "4.0.10",
- "System.Globalization": "4.0.10",
- "System.IO": "4.0.10",
- "System.Linq": "4.0.0",
- "System.Linq.Expressions": "4.0.10",
- "System.ObjectModel": "4.0.10",
- "System.Reflection": "4.0.10",
- "System.Reflection.Extensions": "4.0.0",
- "System.Runtime": "4.0.20",
- "System.Runtime.Extensions": "4.0.10",
- "System.Runtime.Numerics": "4.0.0",
- "System.Runtime.Serialization.Primitives": "4.0.10",
- "System.Text.Encoding": "4.0.10",
- "System.Text.Encoding.Extensions": "4.0.10",
- "System.Text.RegularExpressions": "4.0.10",
- "System.Threading": "4.0.10",
- "System.Threading.Tasks": "4.0.10",
- "System.Xml.ReaderWriter": "4.0.10",
- "System.Xml.XDocument": "4.0.10"
+ "Microsoft.CSharp": "4.0.1-rc2-24027",
+ "System.Collections": "4.0.11-rc2-24027",
+ "System.Diagnostics.Debug": "4.0.11-rc2-24027",
+ "System.Dynamic.Runtime": "4.0.11-rc2-24027",
+ "System.Globalization": "4.0.11-rc2-24027",
+ "System.IO": "4.1.0-rc2-24027",
+ "System.Linq": "4.1.0-rc2-24027",
+ "System.Linq.Expressions": "4.0.11-rc2-24027",
+ "System.ObjectModel": "4.0.12-rc2-24027",
+ "System.Reflection": "4.1.0-rc2-24027",
+ "System.Reflection.Extensions": "4.0.1-rc2-24027",
+ "System.Resources.ResourceManager": "4.0.1-rc2-24027",
+ "System.Runtime": "4.1.0-rc2-24027",
+ "System.Runtime.Extensions": "4.1.0-rc2-24027",
+ "System.Runtime.Serialization.Primitives": "4.1.1-rc2-24027",
+ "System.Text.Encoding": "4.0.11-rc2-24027",
+ "System.Text.Encoding.Extensions": "4.0.11-rc2-24027",
+ "System.Text.RegularExpressions": "4.0.12-rc2-24027",
+ "System.Threading": "4.0.11-rc2-24027",
+ "System.Threading.Tasks": "4.0.11-rc2-24027",
+ "System.Xml.ReaderWriter": "4.0.11-rc2-24027",
+ "System.Xml.XDocument": "4.0.11-rc2-24027"
}
}
}
diff --git a/Src/NuGet.Config b/Src/NuGet.Config
index 8b8ba5bc..be824e1a 100644
--- a/Src/NuGet.Config
+++ b/Src/NuGet.Config
@@ -3,8 +3,8 @@
-
-
-
+
+
\ No newline at end of file
diff --git a/Src/global.json b/Src/global.json
index ae0a7539..0ddf69c7 100644
--- a/Src/global.json
+++ b/Src/global.json
@@ -1,6 +1,3 @@
{
- "projects": [ "src" ],
- "sdk": {
- "version": "1.0.0-rc1-update1"
- }
-}
+ "projects": [ "src" ]
+}
\ No newline at end of file
diff --git a/Tools/Dotnet/install.ps1 b/Tools/Dotnet/install.ps1
new file mode 100644
index 00000000..8b0ac72d
--- /dev/null
+++ b/Tools/Dotnet/install.ps1
@@ -0,0 +1,338 @@
+#
+# Copyright (c) .NET Foundation and contributors. All rights reserved.
+# Licensed under the MIT license. See LICENSE file in the project root for full license information.
+#
+
+<#
+.SYNOPSIS
+ Installs dotnet cli
+.DESCRIPTION
+ Installs dotnet cli. If dotnet installation already exists in the given directory
+ it will update it only if the requested version differs from the one already installed.
+.PARAMETER Channel
+ Default: preview
+ Channel is the way of reasoning about stability and quality of dotnet. This parameter takes one of the values:
+ - future - Possibly unstable, frequently changing, may contain new finished and unfinished features
+ - preview - Pre-release stable with known issues and feature gaps
+ - production - Most stable releases
+.PARAMETER Version
+ Default: latest
+ Represents a build version on specific channel. Possible values:
+ - 4-part version in a format A.B.C.D - represents specific version of build
+ - latest - most latest build on specific channel
+ - lkg - last known good version on specific channel
+ Note: LKG work is in progress. Once the work is finished, this will become new default
+.PARAMETER InstallDir
+ Default: %LocalAppData%\Microsoft\dotnet
+ Path to where to install dotnet. Note that binaries will be placed directly in a given directory.
+.PARAMETER Architecture
+ Default: - this value represents currently running OS architecture
+ Architecture of dotnet binaries to be installed.
+ Possible values are: , x64 and x86
+.PARAMETER DebugSymbols
+ If set the installer will include symbols in the installation.
+.PARAMETER DryRun
+ If set it will not perform installation but instead display what command line to use to consistently install
+ currently requested version of dotnet cli. In example if you specify version 'latest' it will display a link
+ with specific version so that this command can be used deterministicly in a build script.
+ It also displays binaries location if you prefer to install or download it yourself.
+.PARAMETER NoPath
+ By default this script will set environment variable PATH for the current process to the binaries folder inside installation folder.
+ If set it will display binaries location but not set any environment variable.
+.PARAMETER Verbose
+ Displays diagnostics information.
+.PARAMETER AzureFeed
+ Default: https://dotnetcli.blob.core.windows.net/dotnet
+ This parameter should not be usually changed by user. It allows to change URL for the Azure feed used by this installer.
+#>
+[cmdletbinding()]
+param(
+ [string]$Channel="preview",
+ [string]$Version="Latest",
+ [string]$InstallDir="",
+ [string]$Architecture="",
+ [switch]$DebugSymbols, # TODO: Switch does not work yet. Symbols zip is not being uploaded yet.
+ [switch]$DryRun,
+ [switch]$NoPath,
+ [string]$AzureFeed="https://dotnetcli.blob.core.windows.net/dotnet"
+)
+
+Set-StrictMode -Version Latest
+$ErrorActionPreference="Stop"
+$ProgressPreference="SilentlyContinue"
+
+$BinFolderRelativePath=""
+
+# example path with regex: shared/1.0.0-beta-12345/somepath
+$VersionRegEx="/\d+\.\d+[^/]+/"
+$OverrideNonVersionedFiles=$true
+
+function Say($str) {
+ Write-Host "dotnet_install: $str"
+}
+
+function Say-Verbose($str) {
+ Write-Verbose "dotnet_install: $str"
+}
+
+function Say-Invocation($Invocation) {
+ $command = $Invocation.MyCommand;
+ $args = (($Invocation.BoundParameters.Keys | foreach { "-$_ `"$($Invocation.BoundParameters[$_])`"" }) -join " ")
+ Say-Verbose "$command $args"
+}
+
+function Get-Machine-Architecture() {
+ Say-Invocation $MyInvocation
+
+ # possible values: AMD64, IA64, x86
+ return $ENV:PROCESSOR_ARCHITECTURE
+}
+
+# TODO: Architecture and CLIArchitecture should be unified
+function Get-CLIArchitecture-From-Architecture([string]$Architecture) {
+ Say-Invocation $MyInvocation
+
+ switch ($Architecture.ToLower()) {
+ { $_ -eq "" } { return Get-CLIArchitecture-From-Architecture $(Get-Machine-Architecture) }
+ { ($_ -eq "amd64") -or ($_ -eq "x64") } { return "x64" }
+ { $_ -eq "x86" } { return "x86" }
+ default { throw "Architecture not supported. If you think this is a bug, please report it at https://github.com/dotnet/cli/issues" }
+ }
+}
+
+function Get-Version-Info-From-Version-Text([string]$VersionText) {
+ Say-Invocation $MyInvocation
+
+ $Data = @($VersionText.Split([char[]]@(), [StringSplitOptions]::RemoveEmptyEntries));
+
+ $VersionInfo = @{}
+ $VersionInfo.CommitHash = $Data[0].Trim()
+ $VersionInfo.Version = $Data[1].Trim()
+ return $VersionInfo
+}
+
+function Get-Latest-Version-Info([string]$AzureFeed, [string]$AzureChannel, [string]$CLIArchitecture) {
+ Say-Invocation $MyInvocation
+
+ $VersionFileUrl = "$AzureFeed/$AzureChannel/dnvm/latest.win.$CLIArchitecture.version"
+ $Response = Invoke-WebRequest -UseBasicParsing $VersionFileUrl
+ $VersionText = [Text.Encoding]::UTF8.GetString($Response.Content)
+
+ $VersionInfo = Get-Version-Info-From-Version-Text $VersionText
+
+ return $VersionInfo
+}
+
+# TODO: AzureChannel and Channel should be unified
+function Get-Azure-Channel-From-Channel([string]$Channel) {
+ Say-Invocation $MyInvocation
+
+ # For compatibility with build scripts accept also directly Azure channels names
+ switch ($Channel.ToLower()) {
+ { ($_ -eq "future") -or ($_ -eq "dev") } { return "dev" }
+ { ($_ -eq "preview") -or ($_ -eq "beta") } { return "beta" }
+ { $_ -eq "production" } { throw "Production channel does not exist yet" }
+ default { throw "``$Channel`` is an invalid channel name. Use one of the following: ``future``, ``preview``, ``production``" }
+ }
+}
+
+function Get-Specific-Version-From-Version([string]$AzureFeed, [string]$AzureChannel, [string]$CLIArchitecture, [string]$Version) {
+ Say-Invocation $MyInvocation
+
+ switch ($Version.ToLower()) {
+ { $_ -eq "latest" } {
+ $LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -AzureChannel $AzureChannel -CLIArchitecture $CLIArchitecture
+ return $LatestVersionInfo.Version
+ }
+ { $_ -eq "lkg" } { throw "``-Version LKG`` not supported yet." }
+ default { return $Version }
+ }
+}
+
+function Get-Download-Links([string]$AzureFeed, [string]$AzureChannel, [string]$SpecificVersion, [string]$CLIArchitecture) {
+ Say-Invocation $MyInvocation
+
+ $ret = @()
+ $files = @("dotnet-dev")
+
+ foreach ($file in $files) {
+ $PayloadURL = "$AzureFeed/$AzureChannel/Binaries/$SpecificVersion/$file-win-$CLIArchitecture.$SpecificVersion.zip"
+ Say-Verbose "Constructed payload URL: $PayloadURL"
+ $ret += $PayloadURL
+ }
+
+ return $ret
+}
+
+function Get-User-Share-Path() {
+ Say-Invocation $MyInvocation
+
+ $InstallRoot = $env:DOTNET_INSTALL_DIR
+ if (!$InstallRoot) {
+ $InstallRoot = "$env:LocalAppData\Microsoft\dotnet"
+ }
+ return $InstallRoot
+}
+
+function Resolve-Installation-Path([string]$InstallDir) {
+ Say-Invocation $MyInvocation
+
+ if ($InstallDir -eq "") {
+ return Get-User-Share-Path
+ }
+ return $InstallDir
+}
+
+function Get-Version-Info-From-Version-File([string]$InstallRoot, [string]$RelativePathToVersionFile) {
+ Say-Invocation $MyInvocation
+
+ $VersionFile = Join-Path -Path $InstallRoot -ChildPath $RelativePathToVersionFile
+ Say-Verbose "Local version file: $VersionFile"
+
+ if (Test-Path $VersionFile) {
+ $VersionText = cat $VersionFile
+ Say-Verbose "Local version file text: $VersionText"
+ return Get-Version-Info-From-Version-Text $VersionText
+ }
+
+ Say-Verbose "Local version file not found."
+
+ return $null
+}
+
+function Is-Dotnet-Package-Installed([string]$InstallRoot, [string]$RelativePathToPackage, [string]$SpecificVersion) {
+ Say-Invocation $MyInvocation
+
+ $DotnetPackagePath = Join-Path -Path $InstallRoot -ChildPath $RelativePathToPackage | Join-Path -ChildPath $SpecificVersion
+ Say-Verbose "Is-Dotnet-Package-Installed: Path to a package: $DotnetPackagePath"
+ return Test-Path $DotnetPackagePath -PathType Container
+}
+
+function Get-Absolute-Path([string]$RelativeOrAbsolutePath) {
+ # Too much spam
+ # Say-Invocation $MyInvocation
+
+ return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($RelativeOrAbsolutePath)
+}
+
+function Get-Path-Prefix-With-Version($path) {
+ $match = [regex]::match($path, $VersionRegEx)
+ if ($match.Success) {
+ return $entry.FullName.Substring(0, $match.Index + $match.Length)
+ }
+
+ return $null
+}
+
+function Get-List-Of-Directories-And-Versions-To-Unpack-From-Dotnet-Package([System.IO.Compression.ZipArchive]$Zip, [string]$OutPath) {
+ Say-Invocation $MyInvocation
+
+ $ret = @()
+ foreach ($entry in $Zip.Entries) {
+ $dir = Get-Path-Prefix-With-Version $entry.FullName
+ if ($dir -ne $null) {
+ $path = Get-Absolute-Path $(Join-Path -Path $OutPath -ChildPath $dir)
+ if (-Not (Test-Path $path -PathType Container)) {
+ $ret += $dir
+ }
+ }
+ }
+
+ $ret = $ret | Sort-Object | Get-Unique
+
+ $values = ($ret | foreach { "$_" }) -join ";"
+ Say-Verbose "Directories to unpack: $values"
+
+ return $ret
+}
+
+# Example zip content and extraction algorithm:
+# Rule: files if extracted are always being extracted to the same relative path locally
+# .\
+# a.exe # file does not exist locally, extract
+# b.dll # file exists locally, override only if $OverrideFiles set
+# aaa\ # same rules as for files
+# ...
+# abc\1.0.0\ # directory contains version and exists locally
+# ... # do not extract content under versioned part
+# abc\asd\ # same rules as for files
+# ...
+# def\ghi\1.0.1\ # directory contains version and does not exist locally
+# ... # extract content
+function Extract-Dotnet-Package([string]$ZipPath, [string]$OutPath) {
+ Say-Invocation $MyInvocation
+
+ Add-Type -Assembly System.IO.Compression.FileSystem | Out-Null
+ Set-Variable -Name Zip
+ try {
+ $Zip = [System.IO.Compression.ZipFile]::OpenRead($ZipPath)
+
+ $DirectoriesToUnpack = Get-List-Of-Directories-And-Versions-To-Unpack-From-Dotnet-Package -Zip $Zip -OutPath $OutPath
+
+ foreach ($entry in $Zip.Entries) {
+ $PathWithVersion = Get-Path-Prefix-With-Version $entry.FullName
+ if (($PathWithVersion -eq $null) -Or ($DirectoriesToUnpack -contains $PathWithVersion)) {
+ $DestinationPath = Get-Absolute-Path $(Join-Path -Path $OutPath -ChildPath $entry.FullName)
+ $DestinationDir = Split-Path -Parent $DestinationPath
+ $OverrideFiles=$OverrideNonVersionedFiles -Or (-Not (Test-Path $DestinationPath))
+ if ((-Not $DestinationPath.EndsWith("\")) -And $OverrideFiles) {
+ New-Item -ItemType Directory -Force -Path $DestinationDir | Out-Null
+ [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $DestinationPath, $OverrideNonVersionedFiles)
+ }
+ }
+ }
+ }
+ finally {
+ if ($Zip -ne $null) {
+ $Zip.Dispose()
+ }
+ }
+}
+
+$AzureChannel = Get-Azure-Channel-From-Channel -Channel $Channel
+$CLIArchitecture = Get-CLIArchitecture-From-Architecture $Architecture
+$SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $AzureFeed -AzureChannel $AzureChannel -CLIArchitecture $CLIArchitecture -Version $Version
+$DownloadLinks = Get-Download-Links -AzureFeed $AzureFeed -AzureChannel $AzureChannel -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture
+
+if ($DryRun) {
+ Say "Payload URLs:"
+ foreach ($DownloadLink in $DownloadLinks) {
+ Say "- $DownloadLink"
+ }
+ Say "Repeatable invocation: .\$($MyInvocation.MyCommand) -Version $SpecificVersion -Channel $Channel -Architecture $CLIArchitecture -InstallDir $InstallDir"
+ return
+}
+
+$InstallRoot = Resolve-Installation-Path $InstallDir
+Say-Verbose "InstallRoot: $InstallRoot"
+
+$IsSdkInstalled = Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage "sdk" -SpecificVersion $SpecificVersion
+Say-Verbose ".NET SDK installed? $IsSdkInstalled"
+if ($IsSdkInstalled) {
+ Say ".NET SDK version $SpecificVersion is already installed."
+ return
+}
+
+New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null
+
+foreach ($DownloadLink in $DownloadLinks) {
+ $ZipPath = [System.IO.Path]::GetTempFileName()
+ Say "Downloading $DownloadLink"
+ $resp = Invoke-WebRequest -UseBasicParsing $DownloadLink -OutFile $ZipPath
+
+ Say "Extracting zip from $DownloadLink"
+ Extract-Dotnet-Package -ZipPath $ZipPath -OutPath $InstallRoot
+
+ Remove-Item $ZipPath
+}
+
+$BinPath = Get-Absolute-Path $(Join-Path -Path $InstallRoot -ChildPath $BinFolderRelativePath)
+if (-Not $NoPath) {
+ Say "Adding to current process PATH: `"$BinPath`". Note: This change will not be visible if PowerShell was run as a child process."
+ $env:path += ";$BinPath"
+}
+else {
+ Say "Binaries of dotnet can be found in $BinPath"
+}
+
+Say "Installation finished"
diff --git a/Tools/NuGet/NuGet.exe b/Tools/NuGet/NuGet.exe
index 9f8781de..31fc9885 100644
Binary files a/Tools/NuGet/NuGet.exe and b/Tools/NuGet/NuGet.exe differ