Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/Newtonsoft.Json.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
authorJamesNK <james@newtonking.com>2010-09-11 12:06:53 +0400
committerJamesNK <james@newtonking.com>2010-09-11 12:06:53 +0400
commit43501484fbf58864fab17cc975afe60760113725 (patch)
tree6f41d0e6d7d3d341d5e702bd68075865e6d23085 /Src
parent12a91cce9ee0f3675a8df44a9a204137c0b136b9 (diff)
-Added .NET 3.5 build
-Added dynamic support to LINQ to JSON -Added dynamic support to serializer
Diffstat (limited to 'Src')
-rw-r--r--Src/Newtonsoft.Json.Net35.sln26
-rw-r--r--Src/Newtonsoft.Json.Tests/Linq/DynamicTests.cs164
-rw-r--r--Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml7
-rw-r--r--Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml.layout4
-rw-r--r--Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj321
-rw-r--r--Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj3
-rw-r--r--Src/Newtonsoft.Json.Tests/PerformanceTests.cs2
-rw-r--r--Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs6
-rw-r--r--Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs6
-rw-r--r--Src/Newtonsoft.Json.Tests/Serialization/DynamicTests.cs183
-rw-r--r--Src/Newtonsoft.Json.Tests/Serialization/EntitiesSerializationTests.cs2
-rw-r--r--Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs47
-rw-r--r--Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs2
-rw-r--r--Src/Newtonsoft.Json.Tests/SilverlightTests.cs1
-rw-r--r--Src/Newtonsoft.Json/Linq/JObject.cs49
-rw-r--r--Src/Newtonsoft.Json/Linq/JToken.cs121
-rw-r--r--Src/Newtonsoft.Json/Newtonsoft.Json.Net35.csproj265
-rw-r--r--Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj1
-rw-r--r--Src/Newtonsoft.Json/Newtonsoft.Json.csproj4
-rw-r--r--Src/Newtonsoft.Json/Properties/AssemblyInfo.cs2
-rw-r--r--Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs48
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs57
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs2
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs12
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs70
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs41
-rw-r--r--Src/Newtonsoft.Json/Utilities/ConvertUtils.cs2
-rw-r--r--Src/Newtonsoft.Json/Utilities/DynamicProxy.cs94
-rw-r--r--Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs398
-rw-r--r--Src/Newtonsoft.Json/Utilities/DynamicUtils.cs189
-rw-r--r--Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs9
-rw-r--r--Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs12
32 files changed, 2103 insertions, 47 deletions
diff --git a/Src/Newtonsoft.Json.Net35.sln b/Src/Newtonsoft.Json.Net35.sln
new file mode 100644
index 0000000..38664c1
--- /dev/null
+++ b/Src/Newtonsoft.Json.Net35.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.Net35", "Newtonsoft.Json\Newtonsoft.Json.Net35.csproj", "{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.Tests.Net35", "Newtonsoft.Json.Tests\Newtonsoft.Json.Tests.Net35.csproj", "{3E6E2335-B079-4B5B-A65A-9D586914BCBB}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Newtonsoft.Json.Tests/Linq/DynamicTests.cs b/Src/Newtonsoft.Json.Tests/Linq/DynamicTests.cs
new file mode 100644
index 0000000..3ff59ab
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/Linq/DynamicTests.cs
@@ -0,0 +1,164 @@
+#if !(NET35 || NET20 || SILVERLIGHT)
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Linq;
+using NUnit.Framework;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+ public class DynamicTests : TestFixtureBase
+ {
+ [Test]
+ public void JObjectPropertyNames()
+ {
+ JObject o = new JObject(
+ new JProperty("ChildValue", "blah blah"));
+
+ dynamic d = o;
+
+ d.First = "A value!";
+
+ Assert.AreEqual(new JValue("A value!"), d.First);
+ Assert.AreEqual("A value!", (string)d.First);
+
+ d.First = null;
+ Assert.AreEqual(JTokenType.Null, d.First.Type);
+
+ Assert.IsTrue(d.Remove("First"));
+ Assert.IsNull(d.First);
+
+ JValue v1 = d.ChildValue;
+ JValue v2 = d["ChildValue"];
+ Assert.AreEqual(v1, v2);
+
+ JValue newValue1 = new JValue("Blah blah");
+ d.NewValue = newValue1;
+ JValue newValue2 = d.NewValue;
+
+ Assert.IsTrue(ReferenceEquals(newValue1, newValue2));
+ }
+
+ [Test]
+ public void JObjectEnumerator()
+ {
+ JObject o = new JObject(
+ new JProperty("ChildValue", "blah blah"));
+
+ dynamic d = o;
+
+ foreach (JProperty value in d)
+ {
+ Assert.AreEqual("ChildValue", value.Name);
+ Assert.AreEqual("blah blah", (string)value.Value);
+ }
+
+ foreach (dynamic value in d)
+ {
+ Assert.AreEqual("ChildValue", value.Name);
+ Assert.AreEqual("blah blah", (string)value.Value);
+ }
+ }
+
+ [Test]
+ public void JObjectPropertyNameWithJArray()
+ {
+ JObject o = new JObject(
+ new JProperty("ChildValue", "blah blah"));
+
+ dynamic d = o;
+
+ d.First = new JArray();
+ d.First.Add("Hi");
+
+ Assert.AreEqual(1, d.First.Count);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Could not determine JSON object type for type System.String[].")]
+ public void JObjectPropertyNameWithNonToken()
+ {
+ dynamic d = new JObject();
+
+ d.First = new [] {"One", "II", "3"};
+ }
+
+ [Test]
+ public void JObjectMethods()
+ {
+ JObject o = new JObject(
+ new JProperty("ChildValue", "blah blah"));
+
+ dynamic d = o;
+
+ d.Add("NewValue", 1);
+
+ object count = d.Count;
+
+ Assert.IsNull(count);
+ Assert.IsNull(d["Count"]);
+
+ JToken v;
+ Assert.IsTrue(d.TryGetValue("ChildValue", out v));
+ Assert.AreEqual("blah blah", (string)v);
+ }
+
+ [Test]
+ public void JObjectGetDynamicPropertyNames()
+ {
+ JObject o = new JObject(
+ new JProperty("ChildValue", "blah blah"),
+ new JProperty("Hello Joe", null));
+
+ dynamic d = o;
+
+ List<string> memberNames = o.GetDynamicMemberNames().ToList();
+
+ Assert.AreEqual(2, memberNames.Count);
+ Assert.AreEqual("ChildValue", memberNames[0]);
+ Assert.AreEqual("Hello Joe", memberNames[1]);
+ }
+
+ [Test]
+ public void JValueConvert()
+ {
+ AssertValueConverted<bool>(true);
+ AssertValueConverted<bool?>(true);
+ AssertValueConverted<byte[]>(Encoding.UTF8.GetBytes("blah"));
+ AssertValueConverted<DateTime>(new DateTime(2000, 12, 20, 23, 59, 2, DateTimeKind.Utc));
+ AssertValueConverted<DateTime?>(new DateTime(2000, 12, 20, 23, 59, 2, DateTimeKind.Utc));
+ AssertValueConverted<DateTimeOffset>(new DateTimeOffset(2000, 12, 20, 23, 59, 2, TimeSpan.FromHours(1)));
+ AssertValueConverted<DateTimeOffset?>(new DateTimeOffset(2000, 12, 20, 23, 59, 2, TimeSpan.FromHours(1)));
+ AssertValueConverted<decimal>(99.9m);
+ AssertValueConverted<decimal?>(99.9m);
+ AssertValueConverted<double>(99.9);
+ AssertValueConverted<double?>(99.9);
+ AssertValueConverted<float>(99.9f);
+ AssertValueConverted<float?>(99.9f);
+ AssertValueConverted<int>(int.MinValue);
+ AssertValueConverted<int?>(int.MinValue);
+ AssertValueConverted<long>(long.MaxValue);
+ AssertValueConverted<long?>(long.MaxValue);
+ AssertValueConverted<short>(short.MaxValue);
+ AssertValueConverted<short?>(short.MaxValue);
+ AssertValueConverted<string>("blah");
+ AssertValueConverted<uint>(uint.MinValue);
+ AssertValueConverted<uint?>(uint.MinValue);
+ AssertValueConverted<ulong>(ulong.MaxValue);
+ AssertValueConverted<ulong?>(ulong.MaxValue);
+ AssertValueConverted<ushort>(ushort.MinValue);
+ AssertValueConverted<ushort?>(ushort.MinValue);
+ }
+
+ private static void AssertValueConverted<T>(T value)
+ {
+ JValue v = new JValue(value);
+ dynamic d = v;
+
+ Assert.AreEqual(value, (T)d);
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml b/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml
index f1d089f..d43ba51 100644
--- a/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml
+++ b/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml
@@ -1,11 +1,10 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Database Class="LinqToSqlClassesDataContext" xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">
+<?xml version="1.0" encoding="utf-8"?><Database EntityNamespace="Newtonsoft.Json.Tests.LinqToSql" ContextNamespace="Newtonsoft.Json.Tests.LinqToSql" Class="LinqToSqlClassesDataContext" xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">
<Table Name="" Member="Persons">
<Type Name="Person">
<Column Name="FirstName" Type="System.String" CanBeNull="false" />
<Column Name="LastName" Type="System.String" CanBeNull="false" />
<Column Name="PersonId" Type="System.Guid" IsPrimaryKey="true" CanBeNull="false" />
- <Column Member="DepartmentId" Type="System.Guid" CanBeNull="false" />
+ <Column Name="DepartmentId" Type="System.Guid" CanBeNull="false" />
<Association Name="Person_PersonRole" Member="PersonRoles" ThisKey="PersonId" OtherKey="PersonId" Type="PersonRole" />
<Association Name="Department_Person" Member="Department" ThisKey="DepartmentId" OtherKey="DepartmentId" Type="Department" IsForeignKey="true" />
</Type>
@@ -29,7 +28,7 @@
<Table Name="" Member="Departments">
<Type Name="Department">
<Column Name="DepartmentId" Type="System.Guid" IsPrimaryKey="true" CanBeNull="false" />
- <Column Member="Name" Type="System.String" CanBeNull="false" />
+ <Column Name="Name" Type="System.String" CanBeNull="false" />
<Association Name="Department_Person" Member="Persons" ThisKey="DepartmentId" OtherKey="DepartmentId" Type="Person" />
</Type>
</Table>
diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml.layout b/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml.layout
index 8f631b1..c629c33 100644
--- a/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml.layout
+++ b/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml.layout
@@ -20,7 +20,7 @@
<elementListCompartment Id="6865be45-c748-47ff-be37-534064fc2e80" absoluteBounds="3.7649999999999997, 2.71, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
</nestedChildShapes>
</classShape>
- <associationConnector edgePoints="[(2.875 : 2.85179768880208); (3.75 : 2.85179768880208)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+ <associationConnector edgePoints="[(2.875 : 2.85179768880208); (3.75 : 2.85179768880208)]" fixedFrom="NotFixed" fixedTo="NotFixed">
<AssociationMoniker Name="/LinqToSqlClassesDataContext/Person/Person_PersonRole" />
<nodes>
<classShapeMoniker Id="be91ec15-4a64-4976-9358-2e01309ef584" />
@@ -40,7 +40,7 @@
<elementListCompartment Id="46cdd558-04c5-4c77-82ce-fe92cda427fe" absoluteBounds="0.89, 4.96, 1.9700000000000002, 0.63399251302083326" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
</nestedChildShapes>
</classShape>
- <associationConnector edgePoints="[(1.875 : 4.5); (1.875 : 3.45359537760417)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+ <associationConnector edgePoints="[(1.875 : 4.5); (1.875 : 3.45359537760417)]" fixedFrom="NotFixed" fixedTo="NotFixed">
<AssociationMoniker Name="/LinqToSqlClassesDataContext/Department/Department_Person" />
<nodes>
<classShapeMoniker Id="b96fa86b-7f23-489f-8eb2-44ca2af1551b" />
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj
new file mode 100644
index 0000000..55e858c
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj
@@ -0,0 +1,321 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{3E6E2335-B079-4B5B-A65A-9D586914BCBB}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Newtonsoft.Json.Tests.Net35</RootNamespace>
+ <AssemblyName>Newtonsoft.Json.Tests.Net35</AssemblyName>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <SignAssembly>false</SignAssembly>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ <TargetFrameworkProfile>
+ </TargetFrameworkProfile>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\DotNet35\</OutputPath>
+ <DefineConstants>TRACE;DEBUG;NET35</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\DotNet35\</OutputPath>
+ <DefineConstants>TRACE;NET35</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="nunit.framework, Version=2.4.3.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Lib\NUnit\DotNet\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.ComponentModel.DataAnnotations">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Data.Entity">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Runtime.Serialization">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Security" />
+ <Reference Include="System.ServiceModel">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.ServiceModel.Web">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Web" />
+ <Reference Include="System.Web.Extensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Bson\BsonWriterTests.cs" />
+ <Compile Include="Bson\BsonReaderTests.cs" />
+ <Compile Include="Converters\BinaryConverterTests.cs" />
+ <Compile Include="Converters\RegexConverterTests.cs" />
+ <Compile Include="Converters\DataTableConverterTests.cs" />
+ <Compile Include="Converters\DataSetConverterTests.cs" />
+ <Compile Include="Converters\CustomCreationConverterTests.cs" />
+ <Compile Include="Converters\ObjectIdConverterTests.cs" />
+ <Compile Include="Converters\StringEnumConverterTests.cs" />
+ <Compile Include="JsonArrayAttributeTests.cs" />
+ <Compile Include="ExceptionTests.cs" />
+ <Compile Include="JsonValidatingReaderTests.cs" />
+ <Compile Include="LinqToSql\Department.cs" />
+ <Compile Include="LinqToSql\DepartmentConverter.cs" />
+ <Compile Include="LinqToSql\GuidByteArrayConverter.cs" />
+ <Compile Include="LinqToSql\Role.cs" />
+ <Compile Include="LinqToSql\LinqToSqlClasses.designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>LinqToSqlClasses.dbml</DependentUpon>
+ </Compile>
+ <Compile Include="LinqToSql\LinqToSqlClassesSerializationTests.cs" />
+ <Compile Include="LinqToSql\Person.cs" />
+ <Compile Include="Linq\ComponentModel\BindingTests.cs" />
+ <Compile Include="Linq\ComponentModel\JPropertyDescriptorTests.cs" />
+ <Compile Include="Linq\DynamicTests.cs" />
+ <Compile Include="Linq\JPathTests.cs" />
+ <Compile Include="Linq\JRawTests.cs" />
+ <Compile Include="Serialization\ConstructorHandlingTests.cs" />
+ <Compile Include="Serialization\ContractResolverTests.cs" />
+ <Compile Include="Serialization\DefaultValueHandlingTests.cs" />
+ <Compile Include="Serialization\DynamicTests.cs" />
+ <Compile Include="Serialization\NullValueHandlingTests.cs" />
+ <Compile Include="TestObjects\Bar.cs" />
+ <Compile Include="TestObjects\Car.cs" />
+ <Compile Include="TestObjects\Computer.cs" />
+ <Compile Include="TestObjects\ConstructorReadonlyFields.cs" />
+ <Compile Include="TestObjects\Container.cs" />
+ <Compile Include="TestObjects\ContentBaseClass.cs" />
+ <Compile Include="TestObjects\ContentSubClass.cs" />
+ <Compile Include="TestObjects\Foo.cs" />
+ <Compile Include="TestObjects\HolderClass.cs" />
+ <Compile Include="TestObjects\ListOfIds.cs" />
+ <Compile Include="TestObjects\Movie.cs" />
+ <Compile Include="TestObjects\PersonError.cs" />
+ <Compile Include="TestObjects\PersonPropertyClass.cs" />
+ <Compile Include="TestObjects\PrivateConstructorTestClass.cs" />
+ <Compile Include="TestObjects\PrivateConstructorWithPublicParametizedConstructorTestClass.cs" />
+ <Compile Include="TestObjects\Content.cs" />
+ <Compile Include="TestObjects\DateTimeErrorObjectCollection.cs" />
+ <Compile Include="Serialization\EntitiesSerializationTests.cs" />
+ <Compile Include="TestObjects\DictionaryInterfaceClass.cs" />
+ <Compile Include="TestObjects\Event.cs" />
+ <Compile Include="TestObjects\GoogleMapGeocoderStructure.cs" />
+ <Compile Include="TestObjects\InterfacePropertyTestClass.cs" />
+ <Compile Include="TestObjects\JsonPropertyClass.cs" />
+ <Compile Include="TestObjects\ListErrorObject.cs" />
+ <Compile Include="TestObjects\ListErrorObjectCollection.cs" />
+ <Compile Include="Serialization\MissingMemberHandlingTests.cs" />
+ <Compile Include="Serialization\PopulateTests.cs" />
+ <Compile Include="Serialization\SerializationErrorHandlingTests.cs" />
+ <Compile Include="Serialization\SerializationEventAttributeTests.cs" />
+ <Compile Include="Schema\ExtensionsTests.cs" />
+ <Compile Include="Schema\JsonSchemaModelBuilderTests.cs" />
+ <Compile Include="Schema\JsonSchemaNodeTests.cs" />
+ <Compile Include="Serialization\CamelCasePropertyNamesContractResolverTests.cs" />
+ <Compile Include="Serialization\PreserveReferencesHandlingTests.cs" />
+ <Compile Include="Serialization\TypeNameHandlingTests.cs" />
+ <Compile Include="TestObjects\ListTestClass.cs" />
+ <Compile Include="TestObjects\LogEntry.cs" />
+ <Compile Include="TestObjects\NonRequest.cs" />
+ <Compile Include="TestObjects\ObjectArrayPropertyTest.cs" />
+ <Compile Include="TestObjects\SearchResult.cs" />
+ <Compile Include="TestObjects\StructTest.cs" />
+ <Compile Include="TestObjects\WagePerson.cs" />
+ <Compile Include="TestObjects\PropertyCase.cs" />
+ <Compile Include="TestObjects\RequestOnly.cs" />
+ <Compile Include="TestObjects\RoleTransfer.cs" />
+ <Compile Include="TestObjects\SetOnlyPropertyClass2.cs" />
+ <Compile Include="TestObjects\SubKlass.cs" />
+ <Compile Include="TestObjects\SuperKlass.cs" />
+ <Compile Include="TestObjects\VersionKeyedCollection.cs" />
+ <Compile Include="TestObjects\AbstractGenericBase.cs" />
+ <Compile Include="TestObjects\ArgumentConverterPrecedenceClassConverter.cs" />
+ <Compile Include="TestObjects\BadJsonPropertyClass.cs" />
+ <Compile Include="TestObjects\CircularReferenceClass.cs" />
+ <Compile Include="TestObjects\ClassAndMemberConverterClass.cs" />
+ <Compile Include="TestObjects\ClassConverterPrecedenceClassConverter.cs" />
+ <Compile Include="TestObjects\ConstructorCaseSensitivityClass.cs" />
+ <Compile Include="TestObjects\ConverterPrecedenceClass.cs" />
+ <Compile Include="TestObjects\ConverterPrecedenceClassConverter.cs" />
+ <Compile Include="TestObjects\CircularReferenceWithIdClass.cs" />
+ <Compile Include="TestObjects\EmployeeReference.cs" />
+ <Compile Include="TestObjects\JsonPropertyWithHandlingValues.cs" />
+ <Compile Include="TestObjects\DefaultValueAttributeTestClass.cs" />
+ <Compile Include="TestObjects\DoubleClass.cs" />
+ <Compile Include="TestObjects\GenericImpl.cs" />
+ <Compile Include="TestObjects\GenericListAndDictionaryInterfaceProperties.cs" />
+ <Compile Include="TestObjects\GetOnlyPropertyClass.cs" />
+ <Compile Include="TestObjects\IncompatibleJsonAttributeClass.cs" />
+ <Compile Include="TestObjects\Invoice.cs" />
+ <Compile Include="TestObjects\JsonIgnoreAttributeTestClass.cs" />
+ <Compile Include="TestObjects\MemberConverterPrecedenceClassConverter.cs" />
+ <Compile Include="TestObjects\MethodExecutorObject.cs" />
+ <Compile Include="TestObjects\JaggedArray.cs" />
+ <Compile Include="TestObjects\MyClass.cs" />
+ <Compile Include="TestObjects\Name.cs" />
+ <Compile Include="TestObjects\PersonRaw.cs" />
+ <Compile Include="TestObjects\PhoneNumber.cs" />
+ <Compile Include="TestObjects\PrivateMembersClass.cs" />
+ <Compile Include="TestObjects\RequiredMembersClass.cs" />
+ <Compile Include="TestObjects\SerializationEventTestDictionary.cs" />
+ <Compile Include="TestObjects\SerializationEventTestList.cs" />
+ <Compile Include="TestObjects\SerializationEventTestObject.cs" />
+ <Compile Include="TestObjects\SerializationEventTestObjectWithConstructor.cs" />
+ <Compile Include="TestObjects\SetOnlyPropertyClass.cs" />
+ <Compile Include="TestObjects\Article.cs" />
+ <Compile Include="TestObjects\ArticleCollection.cs" />
+ <Compile Include="TestObjects\ClassWithArray.cs" />
+ <Compile Include="TestObjects\ClassWithGuid.cs" />
+ <Compile Include="TestObjects\ConverableMembers.cs" />
+ <Compile Include="TestObjects\JsonIgnoreAttributeOnClassTestClass.cs" />
+ <Compile Include="Linq\JConstructorTests.cs" />
+ <Compile Include="Linq\JPropertyTests.cs" />
+ <Compile Include="TestObjects\MemberConverterClass.cs" />
+ <Compile Include="TestObjects\Product.cs" />
+ <Compile Include="TestObjects\ProductCollection.cs" />
+ <Compile Include="TestObjects\ProductShort.cs" />
+ <Compile Include="TestObjects\Shortie.cs" />
+ <Compile Include="TestObjects\Store.cs" />
+ <Compile Include="TestObjects\StoreColor.cs" />
+ <Compile Include="TestObjects\Person.cs" />
+ <Compile Include="Schema\JsonSchemaBuilderTests.cs" />
+ <Compile Include="Schema\JsonSchemaGeneratorTests.cs" />
+ <Compile Include="Schema\JsonSchemaTests.cs" />
+ <Compile Include="TestObjects\NullableDateTimeTestClass.cs" />
+ <Compile Include="TestObjects\DateTimeTestClass.cs" />
+ <Compile Include="Converters\IsoDateTimeConverterTests.cs" />
+ <Compile Include="JsonConvertTest.cs" />
+ <Compile Include="Converters\JavaScriptDateTimeConverterTests.cs" />
+ <Compile Include="Serialization\JsonSerializerTest.cs" />
+ <Compile Include="JsonTextReaderTest.cs" />
+ <Compile Include="JsonTextWriterTest.cs" />
+ <Compile Include="Linq\JTokenReaderTest.cs" />
+ <Compile Include="Linq\JTokenWriterTest.cs" />
+ <Compile Include="Linq\JArrayTests.cs" />
+ <Compile Include="Linq\JObjectTests.cs" />
+ <Compile Include="Linq\JTokenEqualityComparerTests.cs" />
+ <Compile Include="Linq\JTokenTests.cs" />
+ <Compile Include="Linq\JValueTests.cs" />
+ <Compile Include="Linq\LinqToJsonTest.cs" />
+ <Compile Include="PerformanceTests.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="SilverlightTests.cs" />
+ <Compile Include="TestFixtureBase.cs" />
+ <Compile Include="Converters\XmlNodeConverterTest.cs" />
+ <Compile Include="TestObjects\TypeClass.cs" />
+ <Compile Include="TestObjects\TypedSubHashtable.cs" />
+ <Compile Include="TestObjects\UserNullable.cs" />
+ <Compile Include="Utilities\DynamicReflectionDelegateFactoryTests.cs" />
+ <Compile Include="Utilities\ReflectionUtilsTests.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.Config" />
+ <None Include="LinqToSql\LinqToSqlClasses.dbml">
+ <Generator>MSLinqToSQLGenerator</Generator>
+ <LastGenOutput>LinqToSqlClasses.designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{3259AA49-8AA1-44D3-9025-A0B520596A8C}" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="LinqToSql\LinqToSqlClasses.dbml.layout">
+ <DependentUpon>LinqToSqlClasses.dbml</DependentUpon>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="bunny_pancake.jpg">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+ <Visible>False</Visible>
+ <ProductName>Windows Installer 3.1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Newtonsoft.Json\Newtonsoft.Json.Net35.csproj">
+ <Project>{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}</Project>
+ <Name>Newtonsoft.Json.Net35</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
index dc9423f..5f00323 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
@@ -65,6 +65,7 @@
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="Microsoft.CSharp" />
<Reference Include="nunit.framework, Version=2.4.3.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Lib\NUnit\DotNet\nunit.framework.dll</HintPath>
@@ -134,11 +135,13 @@
<Compile Include="LinqToSql\Person.cs" />
<Compile Include="Linq\ComponentModel\BindingTests.cs" />
<Compile Include="Linq\ComponentModel\JPropertyDescriptorTests.cs" />
+ <Compile Include="Linq\DynamicTests.cs" />
<Compile Include="Linq\JPathTests.cs" />
<Compile Include="Linq\JRawTests.cs" />
<Compile Include="Serialization\ConstructorHandlingTests.cs" />
<Compile Include="Serialization\ContractResolverTests.cs" />
<Compile Include="Serialization\DefaultValueHandlingTests.cs" />
+ <Compile Include="Serialization\DynamicTests.cs" />
<Compile Include="Serialization\NullValueHandlingTests.cs" />
<Compile Include="TestObjects\Bar.cs" />
<Compile Include="TestObjects\Car.cs" />
diff --git a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
index d31ab1d..7667682 100644
--- a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
+++ b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
@@ -1,4 +1,4 @@
-#if !SILVERLIGHT && !PocketPC && !NET20
+#if !SILVERLIGHT && !PocketPC && !NET20 && !NET35
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs
index db5ced4..8cb6a69 100644
--- a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs
@@ -346,11 +346,11 @@ namespace Newtonsoft.Json.Tests.Schema
return base.CreateContract(objectType);
}
- protected override IList<JsonProperty> CreateProperties(JsonObjectContract contract)
+ protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
- IList<JsonProperty> properties = base.CreateProperties(contract);
+ IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
- JsonPropertyCollection c = new JsonPropertyCollection(contract);
+ JsonPropertyCollection c = new JsonPropertyCollection(type);
CollectionUtils.AddRange(c, (IEnumerable)properties.Where(m => m.PropertyName != "Root"));
return c;
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs
index 24221cb..563ef62 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs
@@ -18,12 +18,12 @@ namespace Newtonsoft.Json.Tests.Serialization
_startingWithChar = startingWithChar;
}
- protected override IList<JsonProperty> CreateProperties(JsonObjectContract contract)
+ protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
- IList<JsonProperty> properties = base.CreateProperties(contract);
+ IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
// only serializer properties that start with the specified character
- properties =
+ properties =
properties.Where(p => p.PropertyName.StartsWith(_startingWithChar.ToString())).ToList();
return properties;
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/DynamicTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/DynamicTests.cs
new file mode 100644
index 0000000..7268ddd
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/Serialization/DynamicTests.cs
@@ -0,0 +1,183 @@
+#if !(NET35 || NET20 || SILVERLIGHT)
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization.Formatters;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+ public class DynamicTests : TestFixtureBase
+ {
+ public class DynamicChildObject
+ {
+ public string Text { get; set; }
+ public int Integer { get; set; }
+ }
+
+ public class TestDynamicObject : DynamicObject
+ {
+ private readonly Dictionary<string, object> _members;
+
+ public int Int;
+ public DynamicChildObject ChildObject { get; set; }
+
+ internal Dictionary<string, object> Members
+ {
+ get { return _members; }
+ }
+
+ public TestDynamicObject()
+ {
+ _members = new Dictionary<string, object>();
+ }
+
+ public override IEnumerable<string> GetDynamicMemberNames()
+ {
+ return _members.Keys.Union(new[] { "Int", "ChildObject" });
+ }
+
+ public override bool TryConvert(ConvertBinder binder, out object result)
+ {
+ Type targetType = binder.Type;
+
+ if (targetType == typeof(IDictionary<string, object>) ||
+ targetType == typeof(IDictionary))
+ {
+ result = new Dictionary<string, object>(_members);
+ return true;
+ }
+ else
+ {
+ return base.TryConvert(binder, out result);
+ }
+ }
+
+ public override bool TryDeleteMember(DeleteMemberBinder binder)
+ {
+ return _members.Remove(binder.Name);
+ }
+
+ public override bool TryGetMember(GetMemberBinder binder, out object result)
+ {
+ return _members.TryGetValue(binder.Name, out result);
+ }
+
+ public override bool TrySetMember(SetMemberBinder binder, object value)
+ {
+ _members[binder.Name] = value;
+ return true;
+ }
+ }
+
+ public class ErrorSettingDynamicObject : DynamicObject
+ {
+ public override bool TrySetMember(SetMemberBinder binder, object value)
+ {
+ return false;
+ }
+ }
+
+ [Test]
+ public void SerializeDynamicObject()
+ {
+ TestDynamicObject dynamicObject = new TestDynamicObject();
+
+ dynamic d = dynamicObject;
+ d.Int = 1;
+ d.Decimal = 99.9d;
+ d.ChildObject = new DynamicChildObject();
+
+ Dictionary<string, object> values = new Dictionary<string, object>();
+
+ foreach (string memberName in dynamicObject.GetDynamicMemberNames())
+ {
+ object value;
+ dynamicObject.TryGetMember(memberName, out value);
+
+ values.Add(memberName, value);
+ }
+
+ Assert.AreEqual(d.Int, values["Int"]);
+ Assert.AreEqual(d.Decimal, values["Decimal"]);
+ Assert.AreEqual(d.ChildObject, values["ChildObject"]);
+
+ string json = JsonConvert.SerializeObject(dynamicObject, Formatting.Indented);
+ Assert.AreEqual(@"{
+ ""Decimal"": 99.9,
+ ""Int"": 1,
+ ""ChildObject"": {
+ ""Text"": null,
+ ""Integer"": 0
+ }
+}", json);
+
+ TestDynamicObject newDynamicObject = JsonConvert.DeserializeObject<TestDynamicObject>(json);
+ d = newDynamicObject;
+
+ Assert.AreEqual(99.9, d.Decimal);
+ Assert.AreEqual(1, d.Int);
+ Assert.AreEqual(dynamicObject.ChildObject.Integer, d.ChildObject.Integer);
+ Assert.AreEqual(dynamicObject.ChildObject.Text, d.ChildObject.Text);
+ }
+
+ [Test]
+ public void sdfsdf()
+ {
+ ErrorSettingDynamicObject d = JsonConvert.DeserializeObject<ErrorSettingDynamicObject>("{'hi':5}");
+ }
+
+ [Test]
+ public void SerializeDynamicObjectWithObjectTracking()
+ {
+ dynamic o = new ExpandoObject();
+ o.Text = "Text!";
+ o.Integer = int.MaxValue;
+ o.DynamicChildObject = new DynamicChildObject
+ {
+ Integer = int.MinValue,
+ Text = "Child text!"
+ };
+
+ string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings
+ {
+ TypeNameHandling = TypeNameHandling.All
+ });
+
+ Console.WriteLine(json);
+
+ string dynamicChildObjectTypeName = ReflectionUtils.GetTypeName(typeof(DynamicChildObject), FormatterAssemblyStyle.Simple);
+
+ Assert.AreEqual(@"{
+ ""$type"": ""System.Dynamic.ExpandoObject, System.Core"",
+ ""Text"": ""Text!"",
+ ""Integer"": 2147483647,
+ ""DynamicChildObject"": {
+ ""$type"": """ + dynamicChildObjectTypeName + @""",
+ ""Text"": ""Child text!"",
+ ""Integer"": -2147483648
+ }
+}", json);
+
+ dynamic n = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
+ {
+ TypeNameHandling = TypeNameHandling.All
+ });
+
+ Assert.IsInstanceOfType(typeof(ExpandoObject), n);
+ Assert.AreEqual("Text!", n.Text);
+ Assert.AreEqual(int.MaxValue, n.Integer);
+
+ Assert.IsInstanceOfType(typeof(DynamicChildObject), n.DynamicChildObject);
+ Assert.AreEqual("Child text!", n.DynamicChildObject.Text);
+ Assert.AreEqual(int.MinValue, n.DynamicChildObject.Integer);
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/EntitiesSerializationTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/EntitiesSerializationTests.cs
index 2150e6e..a391ff0 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/EntitiesSerializationTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/EntitiesSerializationTests.cs
@@ -23,7 +23,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
-#if !PocketPC && !SILVERLIGHT && !NET20
+#if !(NET35 || NET20 || SILVERLIGHT)
using System;
using System.Collections.Generic;
using System.Data;
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
index 9990612..32b4e07 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
@@ -27,6 +27,7 @@ using System;
using System.Collections.Generic;
#if !SILVERLIGHT && !PocketPC && !NET20
using System.ComponentModel.DataAnnotations;
+using System.Runtime.CompilerServices;
using System.Web.Script.Serialization;
#endif
using System.Text;
@@ -52,6 +53,10 @@ using System.Reflection;
using System.Xml.Linq;
using System.Text.RegularExpressions;
using System.Collections.Specialized;
+using System.Linq.Expressions;
+#endif
+#if !(NET35 || NET20 || SILVERLIGHT)
+using System.Dynamic;
#endif
namespace Newtonsoft.Json.Tests.Serialization
@@ -3019,7 +3024,7 @@ keyword such as type of business.""
PosDouble p = (PosDouble)value;
if (p != null)
- writer.WriteRawValue(String.Format("new PosD({0},{1})", p.X, p.Y));
+ writer.WriteRawValue(String.Format(CultureInfo.InvariantCulture, "new PosD({0},{1})", p.X, p.Y));
else
writer.WriteNull();
}
@@ -3573,5 +3578,45 @@ keyword such as type of business.""
""event"": ""derived""
}", json);
}
+
+#if !(NET35 || NET20 || SILVERLIGHT)
+ [Test]
+ public void SerializeExpandoObject()
+ {
+ dynamic expando = new ExpandoObject();
+ expando.Int = 1;
+ expando.Decimal = 99.9d;
+ expando.Complex = new ExpandoObject();
+ expando.Complex.String = "I am a string";
+ expando.Complex.DateTime = new DateTime(2000, 12, 20, 18, 55, 0, DateTimeKind.Utc);
+
+ string json = JsonConvert.SerializeObject(expando, Formatting.Indented);
+ Assert.AreEqual(@"{
+ ""Int"": 1,
+ ""Decimal"": 99.9,
+ ""Complex"": {
+ ""String"": ""I am a string"",
+ ""DateTime"": ""\/Date(977338500000)\/""
+ }
+}", json);
+
+ IDictionary<string, object> newExpando = JsonConvert.DeserializeObject<ExpandoObject>(json);
+
+ Assert.IsInstanceOfType(typeof(long), newExpando["Int"]);
+ Assert.AreEqual(expando.Int, newExpando["Int"]);
+
+ Assert.IsInstanceOfType(typeof(double), newExpando["Decimal"]);
+ Assert.AreEqual(expando.Decimal, newExpando["Decimal"]);
+
+ Assert.IsInstanceOfType(typeof(JObject), newExpando["Complex"]);
+ JObject o = (JObject)newExpando["Complex"];
+
+ Assert.IsInstanceOfType(typeof(string), ((JValue)o["String"]).Value);
+ Assert.AreEqual(expando.Complex.String, (string)o["String"]);
+
+ Assert.IsInstanceOfType(typeof(DateTime), ((JValue)o["DateTime"]).Value);
+ Assert.AreEqual(expando.Complex.DateTime, (DateTime)o["DateTime"]);
+ }
+#endif
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs
index 213bb04..e6af2f8 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs
@@ -195,7 +195,7 @@ namespace Newtonsoft.Json.Tests.Serialization
Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]);
Assert.AreEqual(3, errors.Count);
-#if !(NET20 || SILVERLIGHT)
+#if !(NET20 || NET35 || SILVERLIGHT)
Assert.AreEqual("The string was not recognized as a valid DateTime. There is an unknown word starting at index 0.", errors[0]);
#else
Assert.AreEqual("The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.", errors[0]);
diff --git a/Src/Newtonsoft.Json.Tests/SilverlightTests.cs b/Src/Newtonsoft.Json.Tests/SilverlightTests.cs
index edce32e..e1df781 100644
--- a/Src/Newtonsoft.Json.Tests/SilverlightTests.cs
+++ b/Src/Newtonsoft.Json.Tests/SilverlightTests.cs
@@ -4,6 +4,7 @@ using NUnit.Framework;
namespace Newtonsoft.Json.Tests
{
+ // todo: need to fix this to get WP unit tests running off right dlls
#if SILVERLIGHT
[TestFixture]
public class SilverlightTests
diff --git a/Src/Newtonsoft.Json/Linq/JObject.cs b/Src/Newtonsoft.Json/Linq/JObject.cs
index 079fee6..957e1f6 100644
--- a/Src/Newtonsoft.Json/Linq/JObject.cs
+++ b/Src/Newtonsoft.Json/Linq/JObject.cs
@@ -27,6 +27,10 @@ using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
+#if !(NET35 || NET20 || SILVERLIGHT)
+using System.Dynamic;
+using System.Linq.Expressions;
+#endif
using System.Linq;
using System.IO;
using Newtonsoft.Json.Utilities;
@@ -650,5 +654,50 @@ namespace Newtonsoft.Json.Linq
}
#endregion
#endif
+
+#if !(NET35 || NET20 || SILVERLIGHT)
+ /// <summary>
+ /// Returns the <see cref="T:System.Dynamic.DynamicMetaObject"/> responsible for binding operations performed on this object.
+ /// </summary>
+ /// <param name="parameter">The expression tree representation of the runtime value.</param>
+ /// <returns>
+ /// The <see cref="T:System.Dynamic.DynamicMetaObject"/> to bind this object.
+ /// </returns>
+ protected override DynamicMetaObject GetMetaObject(Expression parameter)
+ {
+ return new DynamicProxyMetaObject<JObject>(parameter, new JObjectDynamicProxy(this), true);
+ }
+
+ private class JObjectDynamicProxy : DynamicProxy<JObject>
+ {
+ public JObjectDynamicProxy(JObject value) : base(value)
+ {
+ }
+
+ public override bool TryGetMember(GetMemberBinder binder, out object result)
+ {
+ // result can be null
+ result = Value[binder.Name];
+ return true;
+ }
+
+ public override bool TrySetMember(SetMemberBinder binder, object value)
+ {
+ JToken v = value as JToken;
+
+ // this can throw an error if value isn't a valid for a JValue
+ if (v == null)
+ v = new JValue(value);
+
+ Value[binder.Name] = v;
+ return true;
+ }
+
+ public override IEnumerable<string> GetDynamicMemberNames()
+ {
+ return Value.Properties().Select(p => p.Name);
+ }
+ }
+#endif
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Linq/JToken.cs b/Src/Newtonsoft.Json/Linq/JToken.cs
index ea88bbc..796d58b 100644
--- a/Src/Newtonsoft.Json/Linq/JToken.cs
+++ b/Src/Newtonsoft.Json/Linq/JToken.cs
@@ -25,6 +25,10 @@
using System;
using System.Collections.Generic;
+#if !(NET35 || NET20 || SILVERLIGHT)
+using System.Dynamic;
+using System.Linq.Expressions;
+#endif
using System.Linq;
using System.IO;
using Newtonsoft.Json.Utilities;
@@ -39,7 +43,10 @@ namespace Newtonsoft.Json.Linq
/// Represents an abstract JSON token.
/// </summary>
public abstract class JToken : IJEnumerable<JToken>, IJsonLineInfo
- {
+#if !(NET35 || NET20 || SILVERLIGHT)
+ , IDynamicMetaObjectProvider
+#endif
+ {
private JContainer _parent;
internal JToken _next;
private static JTokenEqualityComparer _equalityComparer;
@@ -562,6 +569,35 @@ namespace Newtonsoft.Json.Linq
}
/// <summary>
+ /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Int16"/>.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ /// <returns>The result of the conversion.</returns>
+ public static explicit operator short(JToken value)
+ {
+ JValue v = EnsureValue(value);
+ if (v == null || !ValidateInteger(v, false))
+ throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+ return Convert.ToInt16(v.Value, CultureInfo.InvariantCulture);
+ }
+
+ /// <summary>
+ /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.UInt16"/>.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ /// <returns>The result of the conversion.</returns>
+ [CLSCompliant(false)]
+ public static explicit operator ushort(JToken value)
+ {
+ JValue v = EnsureValue(value);
+ if (v == null || !ValidateInteger(v, false))
+ throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+ return Convert.ToUInt16(v.Value, CultureInfo.InvariantCulture);
+ }
+
+ /// <summary>
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Int32}"/>.
/// </summary>
/// <param name="value">The value.</param>
@@ -579,6 +615,41 @@ namespace Newtonsoft.Json.Linq
}
/// <summary>
+ /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Int16}"/>.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ /// <returns>The result of the conversion.</returns>
+ public static explicit operator short?(JToken value)
+ {
+ if (value == null)
+ return null;
+
+ JValue v = EnsureValue(value);
+ if (v == null || !ValidateInteger(v, true))
+ throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+ return (v.Value != null) ? (short?)Convert.ToInt16(v.Value, CultureInfo.InvariantCulture) : null;
+ }
+
+ /// <summary>
+ /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{UInt16}"/>.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ /// <returns>The result of the conversion.</returns>
+ [CLSCompliant(false)]
+ public static explicit operator ushort?(JToken value)
+ {
+ if (value == null)
+ return null;
+
+ JValue v = EnsureValue(value);
+ if (v == null || !ValidateInteger(v, true))
+ throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+ return (v.Value != null) ? (ushort?)Convert.ToInt16(v.Value, CultureInfo.InvariantCulture) : null;
+ }
+
+ /// <summary>
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.DateTime"/>.
/// </summary>
/// <param name="value">The value.</param>
@@ -852,6 +923,17 @@ namespace Newtonsoft.Json.Linq
}
/// <summary>
+ /// Performs an implicit conversion from <see cref="Int16"/> to <see cref="JToken"/>.
+ /// </summary>
+ /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+ /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+ [CLSCompliant(false)]
+ public static implicit operator JToken(short value)
+ {
+ return new JValue(value);
+ }
+
+ /// <summary>
/// Performs an implicit conversion from <see cref="UInt16"/> to <see cref="JToken"/>.
/// </summary>
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
@@ -923,6 +1005,17 @@ namespace Newtonsoft.Json.Linq
}
/// <summary>
+ /// Performs an implicit conversion from <see cref="Nullable{Int16}"/> to <see cref="JToken"/>.
+ /// </summary>
+ /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+ /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+ [CLSCompliant(false)]
+ public static implicit operator JToken(short? value)
+ {
+ return new JValue(value);
+ }
+
+ /// <summary>
/// Performs an implicit conversion from <see cref="Nullable{UInt16}"/> to <see cref="JToken"/>.
/// </summary>
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
@@ -1179,5 +1272,31 @@ namespace Newtonsoft.Json.Linq
JPath p = new JPath(path);
return p.Evaluate(this, errorWhenNoMatch);
}
+
+#if !(NET35 || NET20 || SILVERLIGHT)
+ /// <summary>
+ /// Returns the <see cref="T:System.Dynamic.DynamicMetaObject"/> responsible for binding operations performed on this object.
+ /// </summary>
+ /// <param name="parameter">The expression tree representation of the runtime value.</param>
+ /// <returns>
+ /// The <see cref="T:System.Dynamic.DynamicMetaObject"/> to bind this object.
+ /// </returns>
+ protected virtual DynamicMetaObject GetMetaObject(Expression parameter)
+ {
+ return new DynamicProxyMetaObject<JToken>(parameter, new DynamicProxy<JToken>(this), true);
+ }
+
+ /// <summary>
+ /// Returns the <see cref="T:System.Dynamic.DynamicMetaObject"/> responsible for binding operations performed on this object.
+ /// </summary>
+ /// <param name="parameter">The expression tree representation of the runtime value.</param>
+ /// <returns>
+ /// The <see cref="T:System.Dynamic.DynamicMetaObject"/> to bind this object.
+ /// </returns>
+ DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
+ {
+ return GetMetaObject(parameter);
+ }
+#endif
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Net35.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Net35.csproj
new file mode 100644
index 0000000..5edb4bc
--- /dev/null
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Net35.csproj
@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Newtonsoft.Json.Net35</RootNamespace>
+ <AssemblyName>Newtonsoft.Json.Net35</AssemblyName>
+ <SignAssembly>false</SignAssembly>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ <TargetFrameworkProfile>
+ </TargetFrameworkProfile>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\DotNet35\</OutputPath>
+ <DefineConstants>TRACE;DEBUG;CODE_ANALYSIS;NET35</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <DocumentationFile>bin\Debug\DotNet35\Newtonsoft.Json.Net35.xml</DocumentationFile>
+ <RunCodeAnalysis>true</RunCodeAnalysis>
+ <CodeAnalysisRules>
+ </CodeAnalysisRules>
+ <CodeAnalysisRuleSet>Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\DotNet35\</OutputPath>
+ <DefineConstants>TRACE;NET35</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <DocumentationFile>bin\Release\DotNet35\Newtonsoft.Json.Net35.xml</DocumentationFile>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Runtime.Serialization">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Bson\BsonBinaryType.cs" />
+ <Compile Include="Bson\BsonBinaryWriter.cs" />
+ <Compile Include="Bson\BsonReader.cs" />
+ <Compile Include="Bson\BsonToken.cs" />
+ <Compile Include="Bson\BsonType.cs" />
+ <Compile Include="Bson\BsonWriter.cs" />
+ <Compile Include="Bson\BsonObjectId.cs" />
+ <Compile Include="Converters\BinaryConverter.cs" />
+ <Compile Include="Converters\DataSetConverter.cs" />
+ <Compile Include="Converters\DataTableConverter.cs" />
+ <Compile Include="Converters\CustomCreationConverter.cs" />
+ <Compile Include="Converters\DateTimeConverterBase.cs" />
+ <Compile Include="Converters\EntityKeyMemberConverter.cs" />
+ <Compile Include="Converters\KeyValuePairConverter.cs" />
+ <Compile Include="Converters\BsonObjectIdConverter.cs" />
+ <Compile Include="Converters\RegexConverter.cs" />
+ <Compile Include="Converters\StringEnumConverter.cs" />
+ <Compile Include="ConstructorHandling.cs" />
+ <Compile Include="Utilities\DynamicProxy.cs" />
+ <Compile Include="Linq\JPath.cs" />
+ <Compile Include="Linq\JRaw.cs" />
+ <Compile Include="Required.cs" />
+ <Compile Include="Serialization\JsonDynamicContract.cs" />
+ <Compile Include="Serialization\JsonFormatterConverter.cs" />
+ <Compile Include="Serialization\JsonISerializableContract.cs" />
+ <Compile Include="Serialization\JsonLinqContract.cs" />
+ <Compile Include="Serialization\JsonPrimitiveContract.cs" />
+ <Compile Include="Serialization\DynamicValueProvider.cs" />
+ <Compile Include="Serialization\ErrorEventArgs.cs" />
+ <Compile Include="Linq\ComponentModel\JPropertyDescriptor.cs" />
+ <Compile Include="Serialization\DefaultReferenceResolver.cs" />
+ <Compile Include="PreserveReferencesHandling.cs" />
+ <Compile Include="IJsonLineInfo.cs" />
+ <Compile Include="JsonArrayAttribute.cs" />
+ <Compile Include="JsonContainerAttribute.cs" />
+ <Compile Include="DefaultValueHandling.cs" />
+ <Compile Include="JsonConverterAttribute.cs" />
+ <Compile Include="JsonObjectAttribute.cs" />
+ <Compile Include="JsonSerializerSettings.cs" />
+ <Compile Include="JsonValidatingReader.cs" />
+ <Compile Include="Linq\IJEnumerable.cs" />
+ <Compile Include="Linq\JTokenEqualityComparer.cs" />
+ <Compile Include="MemberSerialization.cs" />
+ <Compile Include="ObjectCreationHandling.cs" />
+ <Compile Include="Converters\IsoDateTimeConverter.cs" />
+ <Compile Include="Converters\JavaScriptDateTimeConverter.cs" />
+ <Compile Include="Converters\JsonDateTimeSerializationMode.cs" />
+ <Compile Include="Converters\XmlNodeConverter.cs" />
+ <Compile Include="JsonTextReader.cs" />
+ <Compile Include="JsonPropertyAttribute.cs" />
+ <Compile Include="JsonIgnoreAttribute.cs" />
+ <Compile Include="JsonTextWriter.cs" />
+ <Compile Include="JsonWriterException.cs" />
+ <Compile Include="JsonReaderException.cs" />
+ <Compile Include="JsonConverter.cs" />
+ <Compile Include="JsonConverterCollection.cs" />
+ <Compile Include="JsonReader.cs" />
+ <Compile Include="JsonConvert.cs" />
+ <Compile Include="JsonSerializationException.cs" />
+ <Compile Include="JsonSerializer.cs" />
+ <Compile Include="Linq\Extensions.cs" />
+ <Compile Include="Linq\JConstructor.cs" />
+ <Compile Include="Linq\JContainer.cs" />
+ <Compile Include="Linq\JEnumerable.cs" />
+ <Compile Include="Linq\JObject.cs" />
+ <Compile Include="Linq\JArray.cs" />
+ <Compile Include="Linq\JTokenReader.cs" />
+ <Compile Include="Linq\JTokenWriter.cs" />
+ <Compile Include="Linq\JToken.cs" />
+ <Compile Include="Linq\JProperty.cs" />
+ <Compile Include="Linq\JTokenType.cs" />
+ <Compile Include="Linq\JValue.cs" />
+ <Compile Include="Schema\Extensions.cs" />
+ <Compile Include="Schema\JsonSchemaException.cs" />
+ <Compile Include="Schema\JsonSchemaModel.cs" />
+ <Compile Include="Schema\JsonSchemaModelBuilder.cs" />
+ <Compile Include="Schema\JsonSchemaNodeCollection.cs" />
+ <Compile Include="Schema\JsonSchemaNode.cs" />
+ <Compile Include="Schema\JsonSchemaResolver.cs" />
+ <Compile Include="Schema\JsonSchemaWriter.cs" />
+ <Compile Include="Schema\UndefinedSchemaIdHandling.cs" />
+ <Compile Include="Schema\ValidationEventArgs.cs" />
+ <Compile Include="Schema\ValidationEventHandler.cs" />
+ <Compile Include="Serialization\CamelCasePropertyNamesContractResolver.cs" />
+ <Compile Include="Serialization\DefaultContractResolver.cs" />
+ <Compile Include="Serialization\DefaultSerializationBinder.cs" />
+ <Compile Include="Serialization\ErrorContext.cs" />
+ <Compile Include="Serialization\IContractResolver.cs" />
+ <Compile Include="Serialization\IValueProvider.cs" />
+ <Compile Include="Serialization\JsonArrayContract.cs" />
+ <Compile Include="Serialization\JsonContract.cs" />
+ <Compile Include="Serialization\JsonDictionaryContract.cs" />
+ <Compile Include="Serialization\JsonProperty.cs" />
+ <Compile Include="Serialization\JsonPropertyCollection.cs" />
+ <Compile Include="MissingMemberHandling.cs" />
+ <Compile Include="NullValueHandling.cs" />
+ <Compile Include="ReferenceLoopHandling.cs" />
+ <Compile Include="Schema\JsonSchema.cs" />
+ <Compile Include="Schema\JsonSchemaBuilder.cs" />
+ <Compile Include="Schema\JsonSchemaConstants.cs" />
+ <Compile Include="Schema\JsonSchemaGenerator.cs" />
+ <Compile Include="Serialization\IReferenceResolver.cs" />
+ <Compile Include="Schema\JsonSchemaType.cs" />
+ <Compile Include="Serialization\JsonObjectContract.cs" />
+ <Compile Include="Serialization\JsonSerializerInternalBase.cs" />
+ <Compile Include="Serialization\JsonSerializerInternalReader.cs" />
+ <Compile Include="Serialization\JsonSerializerInternalWriter.cs" />
+ <Compile Include="Serialization\JsonSerializerProxy.cs" />
+ <Compile Include="Serialization\JsonStringContract.cs" />
+ <Compile Include="Serialization\JsonTypeReflector.cs" />
+ <Compile Include="Serialization\CachedAttributeGetter.cs" />
+ <Compile Include="Serialization\LateBoundMetadataTypeAttribute.cs" />
+ <Compile Include="Serialization\ReflectionValueProvider.cs" />
+ <Compile Include="Serialization\OnErrorAttribute.cs" />
+ <Compile Include="Utilities\Base64Encoder.cs" />
+ <Compile Include="Utilities\DynamicProxyMetaObject.cs" />
+ <Compile Include="Utilities\DynamicUtils.cs" />
+ <Compile Include="Utilities\DynamicWrapper.cs" />
+ <Compile Include="Utilities\DynamicReflectionDelegateFactory.cs" />
+ <Compile Include="Serialization\ObjectConstructor.cs" />
+ <Compile Include="Utilities\ILGeneratorExtensions.cs" />
+ <Compile Include="Utilities\ReflectionDelegateFactory.cs" />
+ <Compile Include="Utilities\LateBoundReflectionDelegateFactory.cs" />
+ <Compile Include="Utilities\MethodCall.cs" />
+ <Compile Include="Utilities\ThreadSafeStore.cs" />
+ <Compile Include="TypeNameHandling.cs" />
+ <Compile Include="Utilities\BidirectionalDictionary.cs" />
+ <Compile Include="Utilities\ConvertUtils.cs" />
+ <Compile Include="Utilities\CollectionWrapper.cs" />
+ <Compile Include="Utilities\DateTimeUtils.cs" />
+ <Compile Include="Utilities\DictionaryWrapper.cs" />
+ <Compile Include="Utilities\EnumUtils.cs" />
+ <Compile Include="Utilities\EnumValue.cs" />
+ <Compile Include="Utilities\EnumValues.cs" />
+ <Compile Include="Utilities\JavaScriptUtils.cs" />
+ <Compile Include="JsonToken.cs" />
+ <Compile Include="JsonWriter.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Utilities\StringBuffer.cs" />
+ <Compile Include="Utilities\CollectionUtils.cs" />
+ <Compile Include="Utilities\ListWrapper.cs" />
+ <Compile Include="Utilities\MathUtils.cs" />
+ <Compile Include="Utilities\MiscellaneousUtils.cs" />
+ <Compile Include="Utilities\ReflectionUtils.cs" />
+ <Compile Include="Utilities\StringUtils.cs" />
+ <Compile Include="Utilities\ValidationUtils.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="Dynamic.snk" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
index e11fde6..b0dfbe6 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
@@ -165,6 +165,7 @@
<Compile Include="Serialization\JsonArrayContract.cs" />
<Compile Include="Serialization\JsonContract.cs" />
<Compile Include="Serialization\JsonDictionaryContract.cs" />
+ <Compile Include="Serialization\JsonDynamicContract.cs" />
<Compile Include="Serialization\JsonFormatterConverter.cs" />
<Compile Include="Serialization\JsonISerializableContract.cs" />
<Compile Include="Serialization\JsonLinqContract.cs" />
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
index 5d576f9..153a3e8 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
@@ -102,9 +102,11 @@
<Compile Include="Converters\RegexConverter.cs" />
<Compile Include="Converters\StringEnumConverter.cs" />
<Compile Include="ConstructorHandling.cs" />
+ <Compile Include="Utilities\DynamicProxy.cs" />
<Compile Include="Linq\JPath.cs" />
<Compile Include="Linq\JRaw.cs" />
<Compile Include="Required.cs" />
+ <Compile Include="Serialization\JsonDynamicContract.cs" />
<Compile Include="Serialization\JsonFormatterConverter.cs" />
<Compile Include="Serialization\JsonISerializableContract.cs" />
<Compile Include="Serialization\JsonLinqContract.cs" />
@@ -197,6 +199,8 @@
<Compile Include="Serialization\ReflectionValueProvider.cs" />
<Compile Include="Serialization\OnErrorAttribute.cs" />
<Compile Include="Utilities\Base64Encoder.cs" />
+ <Compile Include="Utilities\DynamicProxyMetaObject.cs" />
+ <Compile Include="Utilities\DynamicUtils.cs" />
<Compile Include="Utilities\DynamicWrapper.cs" />
<Compile Include="Utilities\DynamicReflectionDelegateFactory.cs" />
<Compile Include="Serialization\ObjectConstructor.cs" />
diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
index 2c3fba4..df6333d 100644
--- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
+++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
@@ -46,6 +46,8 @@ using System.Security;
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Compact")]
#elif NET20
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Net20")]
+#elif NET35
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Net35")]
#else
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests")]
#endif
diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
index 6f5adf7..676acbd 100644
--- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
+++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
@@ -27,6 +27,9 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
+#if !(NET35 || NET20 || SILVERLIGHT)
+using System.Dynamic;
+#endif
using System.Globalization;
using System.Linq;
using System.Reflection;
@@ -270,7 +273,7 @@ namespace Newtonsoft.Json.Serialization
InitializeContract(contract);
contract.MemberSerialization = JsonTypeReflector.GetObjectMemberSerialization(objectType);
- contract.Properties.AddRange(CreateProperties(contract));
+ contract.Properties.AddRange(CreateProperties(contract.UnderlyingType, contract.MemberSerialization));
if (contract.DefaultCreator == null || contract.DefaultCreatorNonPublic)
contract.ParametrizedConstructor = GetParametrizedConstructor(objectType);
@@ -443,6 +446,23 @@ namespace Newtonsoft.Json.Serialization
}
#endif
+#if !(NET35 || NET20 || SILVERLIGHT)
+ /// <summary>
+ /// Creates a <see cref="JsonDynamicContract"/> for the given type.
+ /// </summary>
+ /// <param name="objectType">Type of the object.</param>
+ /// <returns>A <see cref="JsonDynamicContract"/> for the given type.</returns>
+ protected virtual JsonDynamicContract CreateDynamicContract(Type objectType)
+ {
+ JsonDynamicContract contract = new JsonDynamicContract(objectType);
+ InitializeContract(contract);
+
+ contract.Properties.AddRange(CreateProperties(objectType, MemberSerialization.OptOut));
+
+ return contract;
+ }
+#endif
+
/// <summary>
/// Creates a <see cref="JsonStringContract"/> for the given type.
/// </summary>
@@ -489,6 +509,11 @@ namespace Newtonsoft.Json.Serialization
return CreateISerializableContract(objectType);
#endif
+#if !(NET35 || NET20 || SILVERLIGHT)
+ if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(objectType))
+ return CreateDynamicContract(objectType);
+#endif
+
return CreateObjectContract(objectType);
}
@@ -563,21 +588,22 @@ namespace Newtonsoft.Json.Serialization
}
/// <summary>
- /// Creates properties for the given <see cref="JsonObjectContract"/>.
+ /// Creates properties for the given <see cref="JsonContract"/>.
/// </summary>
- /// <param name="contract">The contract to create properties for.</param>
- /// <returns>Properties for the given <see cref="JsonObjectContract"/>.</returns>
- protected virtual IList<JsonProperty> CreateProperties(JsonObjectContract contract)
+ /// <param name="type">The type to create properties for.</param>
+ /// /// <param name="memberSerialization">The member serialization mode for the type.</param>
+ /// <returns>Properties for the given <see cref="JsonContract"/>.</returns>
+ protected virtual IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
- List<MemberInfo> members = GetSerializableMembers(contract.UnderlyingType);
+ List<MemberInfo> members = GetSerializableMembers(type);
if (members == null)
throw new JsonSerializationException("Null collection of seralizable members returned.");
- JsonPropertyCollection properties = new JsonPropertyCollection(contract);
+ JsonPropertyCollection properties = new JsonPropertyCollection(type);
foreach (MemberInfo member in members)
{
- JsonProperty property = CreateProperty(contract, member);
+ JsonProperty property = CreateProperty(member, memberSerialization);
if (property != null)
properties.AddProperty(property);
@@ -604,10 +630,10 @@ namespace Newtonsoft.Json.Serialization
/// <summary>
/// Creates a <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.
/// </summary>
- /// <param name="contract">The member's declaring types <see cref="JsonObjectContract"/>.</param>
+ /// <param name="memberSerialization">The member's parent <see cref="MemberSerialization"/>.</param>
/// <param name="member">The member to create a <see cref="JsonProperty"/> for.</param>
/// <returns>A created <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.</returns>
- protected virtual JsonProperty CreateProperty(JsonObjectContract contract, MemberInfo member)
+ protected virtual JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = new JsonProperty();
property.PropertyType = ReflectionUtils.GetMemberUnderlyingType(member);
@@ -652,7 +678,7 @@ namespace Newtonsoft.Json.Serialization
property.Required = Required.Default;
property.Ignored = (hasIgnoreAttribute ||
- (contract.MemberSerialization == MemberSerialization.OptIn
+ (memberSerialization == MemberSerialization.OptIn
&& propertyAttribute == null
#if !PocketPC && !NET20
&& dataMemberAttribute == null
diff --git a/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs b/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs
new file mode 100644
index 0000000..ade8c8a
--- /dev/null
+++ b/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs
@@ -0,0 +1,57 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !(NET35 || NET20 || SILVERLIGHT)
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Newtonsoft.Json.Utilities;
+using System.Collections;
+
+namespace Newtonsoft.Json.Serialization
+{
+ /// <summary>
+ /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+ /// </summary>
+ public class JsonDynamicContract : JsonContract
+ {
+ /// <summary>
+ /// Gets the object's properties.
+ /// </summary>
+ /// <value>The object's properties.</value>
+ public JsonPropertyCollection Properties { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="JsonDynamicContract"/> class.
+ /// </summary>
+ /// <param name="underlyingType">The underlying type for the contract.</param>
+ public JsonDynamicContract(Type underlyingType)
+ : base(underlyingType)
+ {
+ Properties = new JsonPropertyCollection(UnderlyingType);
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs b/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs
index bb07896..e52539f 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs
@@ -58,7 +58,7 @@ namespace Newtonsoft.Json.Serialization
public JsonObjectContract(Type underlyingType)
: base(underlyingType)
{
- Properties = new JsonPropertyCollection(this);
+ Properties = new JsonPropertyCollection(UnderlyingType);
}
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs b/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs
index 8bf17c9..e65fe13 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs
@@ -37,16 +37,16 @@ namespace Newtonsoft.Json.Serialization
/// </summary>
public class JsonPropertyCollection : KeyedCollection<string, JsonProperty>
{
- private readonly JsonObjectContract _contract;
+ private readonly Type _type;
/// <summary>
/// Initializes a new instance of the <see cref="JsonPropertyCollection"/> class.
/// </summary>
- /// <param name="contract">The contract.</param>
- public JsonPropertyCollection(JsonObjectContract contract)
+ /// <param name="type">The type.</param>
+ public JsonPropertyCollection(Type type)
{
- ValidationUtils.ArgumentNotNull(contract, "contract");
- _contract = contract;
+ ValidationUtils.ArgumentNotNull(type, "type");
+ _type = type;
}
/// <summary>
@@ -75,7 +75,7 @@ namespace Newtonsoft.Json.Serialization
if (!existingProperty.Ignored)
throw new JsonSerializationException(
- "A member with the name '{0}' already exists on '{1}'. Use the JsonPropertyAttribute to specify another name.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, _contract.UnderlyingType));
+ "A member with the name '{0}' already exists on '{1}'. Use the JsonPropertyAttribute to specify another name.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, _type));
// remove ignored property so it can be replaced in collection
Remove(existingProperty);
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
index c140241..4ca5afb 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
@@ -27,6 +27,9 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+#if !(NET35 || NET20 || SILVERLIGHT)
+using System.Dynamic;
+#endif
using System.Globalization;
using System.Linq;
using System.Reflection;
@@ -402,6 +405,14 @@ namespace Newtonsoft.Json.Serialization
return CreateISerializable(reader, serializableContract, id);
}
#endif
+
+#if !(NET35 || NET20 || SILVERLIGHT)
+ JsonDynamicContract dynamicContract = contract as JsonDynamicContract;
+ if (dynamicContract != null)
+ {
+ return CreateDynamic(reader, dynamicContract, id);
+ }
+#endif
throw new JsonSerializationException("Cannot deserialize JSON object into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
}
@@ -717,6 +728,7 @@ namespace Newtonsoft.Json.Serialization
if (id != null)
Serializer.ReferenceResolver.AddReference(id, createdObject);
+ // these are together because OnDeserializing takes an object but for an ISerializable the object is full created in the constructor
contract.InvokeOnDeserializing(createdObject, Serializer.Context);
contract.InvokeOnDeserialized(createdObject, Serializer.Context);
@@ -724,6 +736,64 @@ namespace Newtonsoft.Json.Serialization
}
#endif
+#if !(NET35 || NET20 || SILVERLIGHT)
+ private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, string id)
+ {
+ IDynamicMetaObjectProvider newObject = null;
+
+ if (contract.UnderlyingType.IsInterface || contract.UnderlyingType.IsAbstract)
+ throw new JsonSerializationException("Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+
+ if (contract.DefaultCreator != null &&
+ (!contract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
+ {
+ newObject = (IDynamicMetaObjectProvider)contract.DefaultCreator();
+ }
+
+ if (id != null)
+ Serializer.ReferenceResolver.AddReference(id, newObject);
+
+ contract.InvokeOnDeserializing(newObject, Serializer.Context);
+
+ bool exit = false;
+ do
+ {
+ switch (reader.TokenType)
+ {
+ case JsonToken.PropertyName:
+ string memberName = reader.Value.ToString();
+ if (!reader.Read())
+ throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+
+ // first attempt to find a settable property, otherwise fall back to a dynamic set without type
+ JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);
+ if (property != null && property.Writable && !property.Ignored)
+ {
+ SetPropertyValue(property, reader, newObject);
+ }
+ else
+ {
+ object value = (JsonReader.IsPrimitiveToken(reader.TokenType))
+ ? reader.Value
+ : CreateObject(reader, typeof(IDynamicMetaObjectProvider), GetContractSafe(typeof(IDynamicMetaObjectProvider), null), null, null);
+
+ newObject.TrySetMember(memberName, value);
+ }
+ break;
+ case JsonToken.EndObject:
+ exit = true;
+ break;
+ default:
+ throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
+ }
+ } while (!exit && reader.Read());
+
+ contract.InvokeOnDeserialized(newObject, Serializer.Context);
+
+ return newObject;
+ }
+#endif
+
private object CreateAndPopulateObject(JsonReader reader, JsonObjectContract contract, string id)
{
object newObject = null;
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
index b2f6320..fa25fb0 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
@@ -27,6 +27,9 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
+#if !(NET35 || NET20 || SILVERLIGHT)
+using System.Dynamic;
+#endif
using System.Globalization;
using System.Linq;
using System.Reflection;
@@ -132,6 +135,12 @@ namespace Newtonsoft.Json.Serialization
SerializeISerializable(writer, (ISerializable) value, (JsonISerializableContract) valueContract);
}
#endif
+#if !(NET35 || NET20 || SILVERLIGHT)
+ else if (valueContract is JsonDynamicContract)
+ {
+ SerializeDynamic(writer, (IDynamicMetaObjectProvider) value, (JsonDynamicContract) valueContract);
+ }
+#endif
}
private bool ShouldWriteReference(object value, JsonProperty property, JsonContract contract)
@@ -463,18 +472,30 @@ namespace Newtonsoft.Json.Serialization
}
#endif
- //private bool ShouldWriteTypeProperty(JsonProperty member, JsonContract contract, TypeNameHandling typeFlag)
- //{
- // if (HasFlag(((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling, typeFlag))
- // return true;
+#if !(NET35 || NET20 || SILVERLIGHT)
+ private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract)
+ {
+ contract.InvokeOnSerializing(value, Serializer.Context);
+ SerializeStack.Add(value);
- // if ((((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling) == TypeNameHandling.Auto)
+ writer.WriteStartObject();
- // || (member != null
- // && (member.TypeNameHandling ?? Serializer.TypeNameHandling) == TypeNameHandling.Auto
- // && contract.UnderlyingType != member.PropertyType)
- // )
- //}
+ foreach (string memberName in value.GetDynamicMemberNames())
+ {
+ object memberValue;
+ if (DynamicUtils.TryGetMember(value, memberName, out memberValue))
+ {
+ writer.WritePropertyName(memberName);
+ SerializeValue(writer, memberValue, GetContractSafe(memberValue), null, null);
+ }
+ }
+
+ writer.WriteEndObject();
+
+ SerializeStack.RemoveAt(SerializeStack.Count - 1);
+ contract.InvokeOnSerialized(value, Serializer.Context);
+ }
+#endif
private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty member, JsonContract collectionValueContract)
{
diff --git a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
index 6c9b8f2..2cc4f73 100644
--- a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
+++ b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
@@ -235,7 +235,7 @@ namespace Newtonsoft.Json.Utilities
if (targetType == typeof (Uri))
return new Uri((string) initialValue);
if (targetType == typeof (TimeSpan))
-#if !NET20 && !SILVERLIGHT
+#if !(NET35 || NET20 || SILVERLIGHT)
return TimeSpan.Parse((string) initialValue, CultureInfo.InvariantCulture);
#else
return TimeSpan.Parse((string)initialValue);
diff --git a/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs b/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs
new file mode 100644
index 0000000..cadbe93
--- /dev/null
+++ b/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs
@@ -0,0 +1,94 @@
+#if !(NET35 || NET20 || SILVERLIGHT)
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text;
+
+namespace Newtonsoft.Json.Utilities
+{
+ internal class DynamicProxy<T>
+ {
+ public T Value { get; private set; }
+
+ public DynamicProxy(T value)
+ {
+ Value = value;
+ }
+
+ public virtual IEnumerable<string> GetDynamicMemberNames()
+ {
+ return new string[0];
+ }
+
+ public virtual bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result)
+ {
+ result = null;
+ return false;
+ }
+
+ public virtual bool TryConvert(ConvertBinder binder, out object result)
+ {
+ result = null;
+ return false;
+ }
+
+ public virtual bool TryCreateInstance(CreateInstanceBinder binder, object[] args, out object result)
+ {
+ result = null;
+ return false;
+ }
+
+ public virtual bool TryDeleteIndex(DeleteIndexBinder binder, object[] indexes)
+ {
+ return false;
+ }
+
+ public virtual bool TryDeleteMember(DeleteMemberBinder binder)
+ {
+ return false;
+ }
+
+ public virtual bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
+ {
+ result = null;
+ return false;
+ }
+
+ public virtual bool TryGetMember(GetMemberBinder binder, out object result)
+ {
+ result = null;
+ return false;
+ }
+
+ public virtual bool TryInvoke(InvokeBinder binder, object[] args, out object result)
+ {
+ result = null;
+ return false;
+ }
+
+ public virtual bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
+ {
+ result = null;
+ return false;
+ }
+
+ public virtual bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
+ {
+ return false;
+ }
+
+ public virtual bool TrySetMember(SetMemberBinder binder, object value)
+ {
+ return false;
+ }
+
+ public virtual bool TryUnaryOperation(UnaryOperationBinder binder, out object result)
+ {
+ result = null;
+ return false;
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs b/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs
new file mode 100644
index 0000000..58ba434
--- /dev/null
+++ b/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs
@@ -0,0 +1,398 @@
+#if !(NET35 || NET20 || SILVERLIGHT)
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+
+namespace Newtonsoft.Json.Utilities
+{
+ internal sealed class DynamicProxyMetaObject<T> : DynamicMetaObject
+ {
+ private readonly DynamicProxy<T> _proxy;
+ private readonly bool _dontFallbackFirst;
+
+ internal DynamicProxyMetaObject(Expression expression, DynamicProxy<T> proxy, bool dontFallbackFirst)
+ : base(expression, BindingRestrictions.Empty, proxy.Value)
+ {
+ _proxy = proxy;
+ _dontFallbackFirst = dontFallbackFirst;
+ }
+
+ private new T Value { get { return (T)base.Value; } }
+
+ private bool IsOverridden(string method)
+ {
+ return _proxy.GetType().GetMember(method, MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance).Cast<MethodInfo>()
+ .Any(info =>
+ // check that the method overrides the original on DynamicObjectProxy
+ info.DeclaringType != typeof(DynamicProxy<T>) &&
+ info.GetBaseDefinition().DeclaringType == typeof(DynamicProxy<T>));
+ }
+
+ public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
+ {
+ return IsOverridden("TryGetMember")
+ ? CallMethodWithResult("TryGetMember", binder, NoArgs, e => binder.FallbackGetMember(this, e))
+ : base.BindGetMember(binder);
+ }
+
+ public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value)
+ {
+ return IsOverridden("TrySetMember")
+ ? CallMethodReturnLast("TrySetMember", binder, GetArgs(value), e => binder.FallbackSetMember(this, value, e))
+ : base.BindSetMember(binder, value);
+ }
+
+ public override DynamicMetaObject BindDeleteMember(DeleteMemberBinder binder)
+ {
+ return IsOverridden("TryDeleteMember")
+ ? CallMethodNoResult("TryDeleteMember", binder, NoArgs, e => binder.FallbackDeleteMember(this, e))
+ : base.BindDeleteMember(binder);
+ }
+
+
+ public override DynamicMetaObject BindConvert(ConvertBinder binder)
+ {
+ return IsOverridden("TryConvert")
+ ? CallMethodWithResult("TryConvert", binder, NoArgs, e => binder.FallbackConvert(this, e))
+ : base.BindConvert(binder);
+ }
+
+ public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
+ {
+ if (!IsOverridden("TryInvokeMember"))
+ return base.BindInvokeMember(binder, args);
+
+ //
+ // Generate a tree like:
+ //
+ // {
+ // object result;
+ // TryInvokeMember(payload, out result)
+ // ? result
+ // : TryGetMember(payload, out result)
+ // ? FallbackInvoke(result)
+ // : fallbackResult
+ // }
+ //
+ // Then it calls FallbackInvokeMember with this tree as the
+ // "error", giving the language the option of using this
+ // tree or doing .NET binding.
+ //
+ Fallback fallback = e => binder.FallbackInvokeMember(this, args, e);
+
+ DynamicMetaObject call = BuildCallMethodWithResult(
+ "TryInvokeMember",
+ binder,
+ GetArgArray(args),
+ BuildCallMethodWithResult(
+ "TryGetMember",
+ new GetBinderAdapter(binder),
+ NoArgs,
+ fallback(null),
+ e => binder.FallbackInvoke(e, args, null)
+ ),
+ null
+ );
+
+ return _dontFallbackFirst ? call : fallback(call);
+ }
+
+
+ public override DynamicMetaObject BindCreateInstance(CreateInstanceBinder binder, DynamicMetaObject[] args)
+ {
+ return IsOverridden("TryCreateInstance")
+ ? CallMethodWithResult("TryCreateInstance", binder, GetArgArray(args), e => binder.FallbackCreateInstance(this, args, e))
+ : base.BindCreateInstance(binder, args);
+ }
+
+ public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args)
+ {
+ return IsOverridden("TryInvoke")
+ ? CallMethodWithResult("TryInvoke", binder, GetArgArray(args), e => binder.FallbackInvoke(this, args, e))
+ : base.BindInvoke(binder, args);
+ }
+
+ public override DynamicMetaObject BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg)
+ {
+ return IsOverridden("TryBinaryOperation")
+ ? CallMethodWithResult("TryBinaryOperation", binder, GetArgs(arg), e => binder.FallbackBinaryOperation(this, arg, e))
+ : base.BindBinaryOperation(binder, arg);
+ }
+
+ public override DynamicMetaObject BindUnaryOperation(UnaryOperationBinder binder)
+ {
+ return IsOverridden("TryUnaryOperation")
+ ? CallMethodWithResult("TryUnaryOperation", binder, NoArgs, e => binder.FallbackUnaryOperation(this, e))
+ : base.BindUnaryOperation(binder);
+ }
+
+ public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes)
+ {
+ return IsOverridden("TryGetIndex")
+ ? CallMethodWithResult("TryGetIndex", binder, GetArgArray(indexes), e => binder.FallbackGetIndex(this, indexes, e))
+ : base.BindGetIndex(binder, indexes);
+ }
+
+ public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
+ {
+ return IsOverridden("TrySetIndex")
+ ? CallMethodReturnLast("TrySetIndex", binder, GetArgArray(indexes, value), e => binder.FallbackSetIndex(this, indexes, value, e))
+ : base.BindSetIndex(binder, indexes, value);
+ }
+
+ public override DynamicMetaObject BindDeleteIndex(DeleteIndexBinder binder, DynamicMetaObject[] indexes)
+ {
+ return IsOverridden("TryDeleteIndex")
+ ? CallMethodNoResult("TryDeleteIndex", binder, GetArgArray(indexes), e => binder.FallbackDeleteIndex(this, indexes, e))
+ : base.BindDeleteIndex(binder, indexes);
+ }
+
+ private delegate DynamicMetaObject Fallback(DynamicMetaObject errorSuggestion);
+
+ private readonly static Expression[] NoArgs = new Expression[0];
+
+ private static Expression[] GetArgs(params DynamicMetaObject[] args)
+ {
+ return args.Select(arg => Expression.Convert(arg.Expression, typeof(object))).ToArray();
+ }
+
+ private static Expression[] GetArgArray(DynamicMetaObject[] args)
+ {
+ return new[] { Expression.NewArrayInit(typeof(object), GetArgs(args)) };
+ }
+
+ private static Expression[] GetArgArray(DynamicMetaObject[] args, DynamicMetaObject value)
+ {
+ return new Expression[]
+ {
+ Expression.NewArrayInit(typeof(object), GetArgs(args)),
+ Expression.Convert(value.Expression, typeof(object))
+ };
+ }
+
+ private static ConstantExpression Constant(DynamicMetaObjectBinder binder)
+ {
+ Type t = binder.GetType();
+ while (!t.IsVisible)
+ t = t.BaseType;
+ return Expression.Constant(binder, t);
+ }
+
+ /// <summary>
+ /// Helper method for generating a MetaObject which calls a
+ /// specific method on Dynamic that returns a result
+ /// </summary>
+ private DynamicMetaObject CallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback, Fallback fallbackInvoke = null)
+ {
+ //
+ // First, call fallback to do default binding
+ // This produces either an error or a call to a .NET member
+ //
+ DynamicMetaObject fallbackResult = fallback(null);
+
+ DynamicMetaObject callDynamic = BuildCallMethodWithResult(methodName, binder, args, fallbackResult, fallbackInvoke);
+
+ //
+ // Now, call fallback again using our new MO as the error
+ // When we do this, one of two things can happen:
+ // 1. Binding will succeed, and it will ignore our call to
+ // the dynamic method, OR
+ // 2. Binding will fail, and it will use the MO we created
+ // above.
+ //
+
+ return _dontFallbackFirst ? callDynamic : fallback(callDynamic);
+ }
+
+ private DynamicMetaObject BuildCallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke)
+ {
+ //
+ // Build a new expression like:
+ // {
+ // object result;
+ // TryGetMember(payload, out result) ? fallbackInvoke(result) : fallbackResult
+ // }
+ //
+ ParameterExpression result = Expression.Parameter(typeof(object), null);
+
+
+ Expression[] callArgs = new Expression[args.Length + 2];
+ Array.Copy(args, 0, callArgs, 1, args.Length);
+ callArgs[0] = Constant(binder);
+ callArgs[callArgs.Length - 1] = result;
+
+ DynamicMetaObject resultMO = new DynamicMetaObject(result, BindingRestrictions.Empty);
+
+ // Need to add a conversion if calling TryConvert
+ if (binder.ReturnType != typeof (object))
+ {
+ UnaryExpression convert = Expression.Convert(resultMO.Expression, binder.ReturnType);
+ // will always be a cast or unbox
+
+ resultMO = new DynamicMetaObject(convert, resultMO.Restrictions);
+ }
+
+ if (fallbackInvoke != null)
+ resultMO = fallbackInvoke(resultMO);
+
+ DynamicMetaObject callDynamic = new DynamicMetaObject(
+ Expression.Block(
+ new[] {result},
+ Expression.Condition(
+ Expression.Call(
+ Expression.Constant(_proxy),
+ typeof(DynamicProxy<T>).GetMethod(methodName),
+ callArgs
+ ),
+ resultMO.Expression,
+ fallbackResult.Expression,
+ binder.ReturnType
+ )
+ ),
+ GetRestrictions().Merge(resultMO.Restrictions).Merge(fallbackResult.Restrictions)
+ );
+
+ return callDynamic;
+ }
+
+ /// <summary>
+ /// Helper method for generating a MetaObject which calls a
+ /// specific method on Dynamic, but uses one of the arguments for
+ /// the result.
+ /// </summary>
+ private DynamicMetaObject CallMethodReturnLast(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback)
+ {
+ //
+ // First, call fallback to do default binding
+ // This produces either an error or a call to a .NET member
+ //
+ DynamicMetaObject fallbackResult = fallback(null);
+
+ //
+ // Build a new expression like:
+ // {
+ // object result;
+ // TrySetMember(payload, result = value) ? result : fallbackResult
+ // }
+ //
+ ParameterExpression result = Expression.Parameter(typeof(object), null);
+ Expression[] callArgs = AddFirst(args, Constant(binder));
+ callArgs[args.Length] = Expression.Assign(result, callArgs[args.Length]);
+
+ DynamicMetaObject callDynamic = new DynamicMetaObject(
+ Expression.Block(
+ new[] { result },
+ Expression.Condition(
+ Expression.Call(
+ Expression.Constant(_proxy),
+ typeof(DynamicProxy<T>).GetMethod(methodName),
+ callArgs
+ ),
+ result,
+ fallbackResult.Expression,
+ typeof(object)
+ )
+ ),
+ GetRestrictions().Merge(fallbackResult.Restrictions)
+ );
+
+ //
+ // Now, call fallback again using our new MO as the error
+ // When we do this, one of two things can happen:
+ // 1. Binding will succeed, and it will ignore our call to
+ // the dynamic method, OR
+ // 2. Binding will fail, and it will use the MO we created
+ // above.
+ //
+ return _dontFallbackFirst ? callDynamic : fallback(callDynamic);
+ }
+
+ internal static TItem[] AddFirst<TItem>(IList<TItem> list, TItem item)
+ {
+ TItem[] res = new TItem[list.Count + 1];
+ res[0] = item;
+ list.CopyTo(res, 1);
+ return res;
+ }
+
+ /// <summary>
+ /// Helper method for generating a MetaObject which calls a
+ /// specific method on Dynamic, but uses one of the arguments for
+ /// the result.
+ /// </summary>
+ private DynamicMetaObject CallMethodNoResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback)
+ {
+ //
+ // First, call fallback to do default binding
+ // This produces either an error or a call to a .NET member
+ //
+ DynamicMetaObject fallbackResult = fallback(null);
+
+ //
+ // Build a new expression like:
+ // if (TryDeleteMember(payload)) { } else { fallbackResult }
+ //
+ DynamicMetaObject callDynamic = new DynamicMetaObject(
+ Expression.Condition(
+ Expression.Call(
+ Expression.Constant(_proxy),
+ typeof(DynamicProxy<T>).GetMethod(methodName),
+ AddFirst(args, Constant(binder))
+ ),
+ Expression.Empty(),
+ fallbackResult.Expression,
+ typeof (void)
+ ),
+ GetRestrictions().Merge(fallbackResult.Restrictions)
+ );
+
+ //
+ // Now, call fallback again using our new MO as the error
+ // When we do this, one of two things can happen:
+ // 1. Binding will succeed, and it will ignore our call to
+ // the dynamic method, OR
+ // 2. Binding will fail, and it will use the MO we created
+ // above.
+ //
+ return _dontFallbackFirst ? callDynamic : fallback(callDynamic);
+ }
+
+ /// <summary>
+ /// Returns a Restrictions object which includes our current restrictions merged
+ /// with a restriction limiting our type
+ /// </summary>
+ private BindingRestrictions GetRestrictions()
+ {
+ // ReSharper disable CompareNonConstrainedGenericWithNull
+ return Value == null && HasValue // ReSharper restore CompareNonConstrainedGenericWithNull
+ ? BindingRestrictions.GetInstanceRestriction(Expression, null)
+ : BindingRestrictions.GetTypeRestriction(Expression, LimitType);
+ }
+
+ public override IEnumerable<string> GetDynamicMemberNames()
+ {
+ return _proxy.GetDynamicMemberNames();
+ }
+
+ // It is okay to throw NotSupported from this binder. This object
+ // is only used by DynamicObject.GetMember--it is not expected to
+ // (and cannot) implement binding semantics. It is just so the DO
+ // can use the Name and IgnoreCase properties.
+ private sealed class GetBinderAdapter : GetMemberBinder
+ {
+ internal GetBinderAdapter(InvokeMemberBinder binder) :
+ base(binder.Name, binder.IgnoreCase)
+ {
+ }
+
+ public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
+ {
+ throw new NotSupportedException();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs b/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs
new file mode 100644
index 0000000..75b9ac3
--- /dev/null
+++ b/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs
@@ -0,0 +1,189 @@
+#if !(NET35 || NET20 || SILVERLIGHT)
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Utilities
+{
+ internal static class DynamicUtils
+ {
+ internal static class BinderWrapper
+ {
+ private const string BinderTypeName = "Microsoft.CSharp.RuntimeBinder.Binder, Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
+ private const string CSharpArgumentInfoTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo, Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
+ private const string CSharpArgumentInfoFlagsTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
+ private const string CSharpBinderFlagsTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
+
+ private static object _getCSharpArgumentInfoArray;
+ private static object _setCSharpArgumentInfoArray;
+ private static MethodCall<object, object> _getMemberCall;
+ private static MethodCall<object, object> _setMemberCall;
+ private static bool _init;
+
+ private static void Init()
+ {
+ if (!_init)
+ {
+ Type binderType = Type.GetType(BinderTypeName, false);
+ if (binderType == null)
+ throw new Exception("Could not resolve type '{0}'. You may need to add a reference to Microsoft.CSharp.dll to work with dynamic types.".FormatWith(CultureInfo.InvariantCulture, BinderTypeName));
+
+ // None
+ _getCSharpArgumentInfoArray = CreateSharpArgumentInfoArray(0);
+ // None, Constant | UseCompileTimeType
+ _setCSharpArgumentInfoArray = CreateSharpArgumentInfoArray(0, 3);
+ CreateMemberCalls();
+
+ _init = true;
+ }
+ }
+
+ private static object CreateSharpArgumentInfoArray(params int[] values)
+ {
+ Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName);
+ Type csharpArgumentInfoFlags = Type.GetType(CSharpArgumentInfoFlagsTypeName);
+
+ Array a = Array.CreateInstance(csharpArgumentInfoType, values.Length);
+
+ for (int i = 0; i < values.Length; i++)
+ {
+ MethodInfo createArgumentInfoMethod = csharpArgumentInfoType.GetMethod("Create", BindingFlags.Public | BindingFlags.Static, null, new[] { csharpArgumentInfoFlags, typeof(string) }, null);
+ object arg = createArgumentInfoMethod.Invoke(null, new object[] { 0, null });
+ a.SetValue(arg, i);
+ }
+
+ return a;
+ }
+
+ private static void CreateMemberCalls()
+ {
+ Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName);
+ Type csharpBinderFlagsType = Type.GetType(CSharpBinderFlagsTypeName);
+ Type binderType = Type.GetType(BinderTypeName);
+
+ Type csharpArgumentInfoTypeEnumerableType = typeof(IEnumerable<>).MakeGenericType(csharpArgumentInfoType);
+
+ MethodInfo getMemberMethod = binderType.GetMethod("GetMember", BindingFlags.Public | BindingFlags.Static, null, new[] { csharpBinderFlagsType, typeof(string), typeof(Type), csharpArgumentInfoTypeEnumerableType }, null);
+ _getMemberCall = DynamicReflectionDelegateFactory.Instance.CreateMethodCall<object>(getMemberMethod);
+
+ MethodInfo setMemberMethod = binderType.GetMethod("SetMember", BindingFlags.Public | BindingFlags.Static, null, new[] { csharpBinderFlagsType, typeof(string), typeof(Type), csharpArgumentInfoTypeEnumerableType }, null);
+ _setMemberCall = DynamicReflectionDelegateFactory.Instance.CreateMethodCall<object>(setMemberMethod);
+ }
+
+ public static CallSiteBinder GetMember(string name, Type context)
+ {
+ Init();
+ return (CallSiteBinder)_getMemberCall(null, 0, name, context, _getCSharpArgumentInfoArray);
+ }
+
+ public static CallSiteBinder SetMember(string name, Type context)
+ {
+ Init();
+ return (CallSiteBinder)_setMemberCall(null, 0, name, context, _setCSharpArgumentInfoArray);
+ }
+ }
+
+ public static bool TryGetMember(this IDynamicMetaObjectProvider dynamicProvider, string name, out object value)
+ {
+ GetMemberBinder getMemberBinder = (GetMemberBinder) BinderWrapper.GetMember(name, typeof (DynamicUtils));
+
+ CallSite<Func<CallSite, object, object>> callSite = CallSite<Func<CallSite, object, object>>.Create(new NoThrowGetBinderMember(getMemberBinder));
+
+ object result = callSite.Target(callSite, dynamicProvider);
+
+ if (!ReferenceEquals(result, NoThrowExpressionVisitor.ErrorResult))
+ {
+ value = result;
+ return true;
+ }
+ else
+ {
+ value = null;
+ return false;
+ }
+ }
+
+ public static bool TrySetMember(this IDynamicMetaObjectProvider dynamicProvider, string name, object value)
+ {
+ SetMemberBinder binder = (SetMemberBinder) BinderWrapper.SetMember(name, value.GetType());
+
+ var setterSite = CallSite<Func<CallSite, object, object, object>>.Create(new NoThrowSetBinderMember(binder));
+
+ object result = setterSite.Target(setterSite, dynamicProvider, value);
+
+ return !ReferenceEquals(result, NoThrowExpressionVisitor.ErrorResult);
+ }
+
+ public static IEnumerable<string> GetDynamicMemberNames(this IDynamicMetaObjectProvider dynamicProvider)
+ {
+ DynamicMetaObject metaObject = dynamicProvider.GetMetaObject(Expression.Constant(dynamicProvider));
+ return metaObject.GetDynamicMemberNames();
+ }
+
+ internal class NoThrowGetBinderMember : GetMemberBinder
+ {
+ private readonly GetMemberBinder _innerBinder;
+
+ public NoThrowGetBinderMember(GetMemberBinder innerBinder)
+ : base(innerBinder.Name, innerBinder.IgnoreCase)
+ {
+ _innerBinder = innerBinder;
+ }
+
+ public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
+ {
+ DynamicMetaObject retMetaObject = _innerBinder.Bind(target, new DynamicMetaObject[] { });
+
+ NoThrowExpressionVisitor noThrowVisitor = new NoThrowExpressionVisitor();
+ Expression resultExpression = noThrowVisitor.Visit(retMetaObject.Expression);
+
+ DynamicMetaObject finalMetaObject = new DynamicMetaObject(resultExpression, retMetaObject.Restrictions);
+ return finalMetaObject;
+ }
+ }
+
+ internal class NoThrowSetBinderMember : SetMemberBinder
+ {
+ private readonly SetMemberBinder _innerBinder;
+
+ public NoThrowSetBinderMember(SetMemberBinder innerBinder)
+ : base(innerBinder.Name, innerBinder.IgnoreCase)
+ {
+ _innerBinder = innerBinder;
+ }
+
+ public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
+ {
+ DynamicMetaObject retMetaObject = _innerBinder.Bind(target, new DynamicMetaObject[] { value });
+
+ NoThrowExpressionVisitor noThrowVisitor = new NoThrowExpressionVisitor();
+ Expression resultExpression = noThrowVisitor.Visit(retMetaObject.Expression);
+
+ DynamicMetaObject finalMetaObject = new DynamicMetaObject(resultExpression, retMetaObject.Restrictions);
+ return finalMetaObject;
+ }
+ }
+
+
+ internal class NoThrowExpressionVisitor : ExpressionVisitor
+ {
+ internal static readonly object ErrorResult = new object();
+
+ protected override Expression VisitConditional(ConditionalExpression node)
+ {
+ // if the result of a test is to throw an error, rewrite to result an error result value
+ if (node.IfFalse.NodeType == ExpressionType.Throw)
+ return Expression.Condition(node.Test, node.IfTrue, Expression.Constant(ErrorResult));
+
+ return base.VisitConditional(node);
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs b/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs
index 6c80c65..8e88819 100644
--- a/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs
+++ b/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs
@@ -53,7 +53,14 @@ namespace Newtonsoft.Json.Utilities
private static byte[] GetStrongKey()
{
- using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Newtonsoft.Json.Dynamic.snk"))
+ string name;
+#if NET35
+ name = "Newtonsoft.Json.Net35.Dynamic.snk";
+#else
+ name = "Newtonsoft.Json.Dynamic.snk";
+#endif
+
+ using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
{
if (stream == null)
throw new MissingManifestResourceException("Should have a Newtonsoft.Json.Dynamic.snk as an embedded resource.");
diff --git a/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs b/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs
index e112ab4..11ae690 100644
--- a/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs
+++ b/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs
@@ -35,6 +35,8 @@ namespace Newtonsoft.Json.Utilities
public override MethodCall<T, object> CreateMethodCall<T>(MethodBase method)
{
+ ValidationUtils.ArgumentNotNull(method, "method");
+
ConstructorInfo c = method as ConstructorInfo;
if (c != null)
return (o, a) => c.Invoke(a);
@@ -44,6 +46,8 @@ namespace Newtonsoft.Json.Utilities
public override Func<T> CreateDefaultConstructor<T>(Type type)
{
+ ValidationUtils.ArgumentNotNull(type, "type");
+
if (type.IsValueType)
return () => (T)ReflectionUtils.CreateInstance(type);
@@ -54,21 +58,29 @@ namespace Newtonsoft.Json.Utilities
public override Func<T, object> CreateGet<T>(PropertyInfo propertyInfo)
{
+ ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo");
+
return o => propertyInfo.GetValue(o, null);
}
public override Func<T, object> CreateGet<T>(FieldInfo fieldInfo)
{
+ ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo");
+
return o => fieldInfo.GetValue(o);
}
public override Action<T, object> CreateSet<T>(FieldInfo fieldInfo)
{
+ ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo");
+
return (o, v) => fieldInfo.SetValue(o, v);
}
public override Action<T, object> CreateSet<T>(PropertyInfo propertyInfo)
{
+ ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo");
+
return (o, v) => propertyInfo.SetValue(o, v, null);
}
}