diff --git a/Mvc.NoFun.sln b/Mvc.NoFun.sln
index 360ba19994..d13841b640 100644
--- a/Mvc.NoFun.sln
+++ b/Mvc.NoFun.sln
@@ -48,10 +48,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.PageExecut
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.TestCommon", "test\Microsoft.AspNet.Mvc.TestCommon\Microsoft.AspNet.Mvc.TestCommon.xproj", "{F504357E-C2E1-4818-BA5C-9A2EAC25FEE5}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.JsonPatch.Test", "test\Microsoft.AspNet.JsonPatch.Test\Microsoft.AspNet.JsonPatch.Test.xproj", "{81C20848-E063-4E12-AC40-0B55A532C16C}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.JsonPatch", "src\Microsoft.AspNet.JsonPatch\Microsoft.AspNet.JsonPatch.xproj", "{4D55F4D8-633B-462F-A5B1-FEB84BD2D534}"
-EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.IntegrationTests", "test\Microsoft.AspNet.Mvc.IntegrationTests\Microsoft.AspNet.Mvc.IntegrationTests.xproj", "{864FA09D-1E48-403A-A6C8-4F079D2A30F0}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Abstractions", "src\Microsoft.AspNet.Mvc.Abstractions\Microsoft.AspNet.Mvc.Abstractions.xproj", "{1154203C-7579-4525-906E-BC55268421C1}"
@@ -280,29 +276,6 @@ Global
{F504357E-C2E1-4818-BA5C-9A2EAC25FEE5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{F504357E-C2E1-4818-BA5C-9A2EAC25FEE5}.Release|x86.ActiveCfg = Release|Any CPU
{F504357E-C2E1-4818-BA5C-9A2EAC25FEE5}.Release|x86.Build.0 = Release|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|x86.ActiveCfg = Debug|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|x86.Build.0 = Debug|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|Any CPU.Build.0 = Release|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|x86.ActiveCfg = Release|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|x86.Build.0 = Release|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|x86.ActiveCfg = Debug|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|x86.Build.0 = Debug|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Release|Any CPU.Build.0 = Release|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Release|x86.ActiveCfg = Release|Any CPU
{864FA09D-1E48-403A-A6C8-4F079D2A30F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{864FA09D-1E48-403A-A6C8-4F079D2A30F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{864FA09D-1E48-403A-A6C8-4F079D2A30F0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -553,8 +526,6 @@ Global
{860119ED-3DB1-424D-8D0A-30132A8A7D96} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{4DA2D7C1-A7B6-4C01-B57D-89E6EA4609DE} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{F504357E-C2E1-4818-BA5C-9A2EAC25FEE5} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
- {81C20848-E063-4E12-AC40-0B55A532C16C} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{864FA09D-1E48-403A-A6C8-4F079D2A30F0} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{1154203C-7579-4525-906E-BC55268421C1} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{DA000953-7532-4DF5-8DB9-8143DF98D999} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
diff --git a/Mvc.sln b/Mvc.sln
index 15ef1264d1..5e9a1d721d 100644
--- a/Mvc.sln
+++ b/Mvc.sln
@@ -140,10 +140,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CorsWebSite", "test\WebSite
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CorsMiddlewareWebSite", "test\WebSites\CorsMiddlewareWebSite\CorsMiddlewareWebSite.xproj", "{B42D4844-FFF8-4EC2-88D1-3AE95234D9EB}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.JsonPatch.Test", "test\Microsoft.AspNet.JsonPatch.Test\Microsoft.AspNet.JsonPatch.Test.xproj", "{81C20848-E063-4E12-AC40-0B55A532C16C}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.JsonPatch", "src\Microsoft.AspNet.JsonPatch\Microsoft.AspNet.JsonPatch.xproj", "{4D55F4D8-633B-462F-A5B1-FEB84BD2D534}"
-EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "JsonPatchWebSite", "test\WebSites\JsonPatchWebSite\JsonPatchWebSite.xproj", "{DAB1252D-577C-4912-98BE-1A812BF83F86}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.IntegrationTests", "test\Microsoft.AspNet.Mvc.IntegrationTests\Microsoft.AspNet.Mvc.IntegrationTests.xproj", "{864FA09D-1E48-403A-A6C8-4F079D2A30F0}"
@@ -865,30 +861,6 @@ Global
{B42D4844-FFF8-4EC2-88D1-3AE95234D9EB}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{B42D4844-FFF8-4EC2-88D1-3AE95234D9EB}.Release|x86.ActiveCfg = Release|Any CPU
{B42D4844-FFF8-4EC2-88D1-3AE95234D9EB}.Release|x86.Build.0 = Release|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|x86.ActiveCfg = Debug|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|x86.Build.0 = Debug|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|Any CPU.Build.0 = Release|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|x86.ActiveCfg = Release|Any CPU
- {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|x86.Build.0 = Release|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|x86.ActiveCfg = Debug|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|x86.Build.0 = Debug|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Release|Any CPU.Build.0 = Release|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Release|x86.ActiveCfg = Release|Any CPU
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Release|x86.Build.0 = Release|Any CPU
{DAB1252D-577C-4912-98BE-1A812BF83F86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DAB1252D-577C-4912-98BE-1A812BF83F86}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DAB1252D-577C-4912-98BE-1A812BF83F86}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -1221,8 +1193,6 @@ Global
{F504357E-C2E1-4818-BA5C-9A2EAC25FEE5} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{94BA134D-04B3-48AA-BA55-5A4DB8640F2D} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{B42D4844-FFF8-4EC2-88D1-3AE95234D9EB} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
- {81C20848-E063-4E12-AC40-0B55A532C16C} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
- {4D55F4D8-633B-462F-A5B1-FEB84BD2D534} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{DAB1252D-577C-4912-98BE-1A812BF83F86} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{864FA09D-1E48-403A-A6C8-4F079D2A30F0} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{1154203C-7579-4525-906E-BC55268421C1} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
diff --git a/src/Microsoft.AspNet.JsonPatch/Adapters/IObjectAdapter.cs b/src/Microsoft.AspNet.JsonPatch/Adapters/IObjectAdapter.cs
deleted file mode 100644
index 724dfe3f79..0000000000
--- a/src/Microsoft.AspNet.JsonPatch/Adapters/IObjectAdapter.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using Microsoft.AspNet.JsonPatch.Operations;
-
-namespace Microsoft.AspNet.JsonPatch.Adapters
-{
- ///
- /// Defines the operations that can be performed on a JSON patch document.
- ///
- public interface IObjectAdapter
- {
- void Add(Operation operation, object objectToApplyTo);
- void Copy(Operation operation, object objectToApplyTo);
- void Move(Operation operation, object objectToApplyTo);
- void Remove(Operation operation, object objectToApplyTo);
- void Replace(Operation operation, object objectToApplyTo);
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.JsonPatch/Adapters/ObjectAdapter.cs b/src/Microsoft.AspNet.JsonPatch/Adapters/ObjectAdapter.cs
deleted file mode 100644
index 4640e97039..0000000000
--- a/src/Microsoft.AspNet.JsonPatch/Adapters/ObjectAdapter.cs
+++ /dev/null
@@ -1,1105 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Reflection;
-using Microsoft.AspNet.JsonPatch.Exceptions;
-using Microsoft.AspNet.JsonPatch.Helpers;
-using Microsoft.AspNet.JsonPatch.Operations;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Serialization;
-
-namespace Microsoft.AspNet.JsonPatch.Adapters
-{
- ///
- public class ObjectAdapter : IObjectAdapter
- {
- ///
- /// Initializes a new instance of .
- ///
- /// The .
- /// The for logging .
- public ObjectAdapter(
- IContractResolver contractResolver,
- Action logErrorAction)
- {
- if (contractResolver == null)
- {
- throw new ArgumentNullException(nameof(contractResolver));
- }
-
- ContractResolver = contractResolver;
- LogErrorAction = logErrorAction;
- }
-
- ///
- /// Gets or sets the .
- ///
- public IContractResolver ContractResolver { get; }
-
- ///
- /// Action for logging .
- ///
- public Action LogErrorAction { get; }
-
- ///
- /// The "add" operation performs one of the following functions,
- /// depending upon what the target location references:
- ///
- /// o If the target location specifies an array index, a new value is
- /// inserted into the array at the specified index.
- ///
- /// o If the target location specifies an object member that does not
- /// already exist, a new member is added to the object.
- ///
- /// o If the target location specifies an object member that does exist,
- /// that member's value is replaced.
- ///
- /// The operation object MUST contain a "value" member whose content
- /// specifies the value to be added.
- ///
- /// For example:
- ///
- /// { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] }
- ///
- /// When the operation is applied, the target location MUST reference one
- /// of:
- ///
- /// o The root of the target document - whereupon the specified value
- /// becomes the entire content of the target document.
- ///
- /// o A member to add to an existing object - whereupon the supplied
- /// value is added to that object at the indicated location. If the
- /// member already exists, it is replaced by the specified value.
- ///
- /// o An element to add to an existing array - whereupon the supplied
- /// value is added to the array at the indicated location. Any
- /// elements at or above the specified index are shifted one position
- /// to the right. The specified index MUST NOT be greater than the
- /// number of elements in the array. If the "-" character is used to
- /// index the end of the array (see [RFC6901]), this has the effect of
- /// appending the value to the array.
- ///
- /// Because this operation is designed to add to existing objects and
- /// arrays, its target location will often not exist. Although the
- /// pointer's error handling algorithm will thus be invoked, this
- /// specification defines the error handling behavior for "add" pointers
- /// to ignore that error and add the value as specified.
- ///
- /// However, the object itself or an array containing it does need to
- /// exist, and it remains an error for that not to be the case. For
- /// example, an "add" with a target location of "/a/b" starting with this
- /// document:
- ///
- /// { "a": { "foo": 1 } }
- ///
- /// is not an error, because "a" exists, and "b" will be added to its
- /// value. It is an error in this document:
- ///
- /// { "q": { "bar": 2 } }
- ///
- /// because "a" does not exist.
- ///
- /// The add operation.
- /// Object to apply the operation to.
- public void Add(Operation operation, object objectToApplyTo)
- {
- if (operation == null)
- {
- throw new ArgumentNullException(nameof(operation));
- }
-
- if (objectToApplyTo == null)
- {
- throw new ArgumentNullException(nameof(objectToApplyTo));
- }
-
- Add(operation.path, operation.value, objectToApplyTo, operation);
- }
-
- ///
- /// Add is used by various operations (eg: add, copy, ...), yet through different operations;
- /// This method allows code reuse yet reporting the correct operation on error
- ///
- private void Add(
- string path,
- object value,
- object objectToApplyTo,
- Operation operationToReport)
- {
- if (path == null)
- {
- throw new ArgumentNullException(nameof(path));
- }
-
- if (objectToApplyTo == null)
- {
- throw new ArgumentNullException(nameof(objectToApplyTo));
- }
-
- if (operationToReport == null)
- {
- throw new ArgumentNullException(nameof(operationToReport));
- }
-
- // first up: if the path ends in a numeric value, we're inserting in a list and
- // that value represents the position; if the path ends in "-", we're appending
- // to the list.
-
- // get path result
- var pathResult = GetActualPropertyPath(
- path,
- objectToApplyTo,
- operationToReport);
- if (pathResult == null)
- {
- return;
- }
-
- var appendList = pathResult.ExecuteAtEnd;
- var positionAsInteger = pathResult.NumericEnd;
- var actualPathToProperty = pathResult.PathToProperty;
-
- var treeAnalysisResult = new ObjectTreeAnalysisResult(
- objectToApplyTo,
- actualPathToProperty,
- ContractResolver);
-
- if (!treeAnalysisResult.IsValidPathForAdd)
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatPropertyCannotBeAdded(path)));
- return;
- }
-
- if (treeAnalysisResult.UseDynamicLogic)
- {
- var container = treeAnalysisResult.Container;
- if (container.ContainsCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent))
- {
- // Existing property.
- // If it's not an array, we need to check if the value fits the property type
- //
- // If it's an array, we need to check if the value fits in that array type,
- // and add it at the correct position (if allowed).
- if (appendList || positionAsInteger > -1)
- {
- // get the actual type
- var propertyValue = container.GetValueForCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent);
- var typeOfPathProperty = propertyValue.GetType();
-
- if (!IsNonStringArray(typeOfPathProperty))
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path)));
- return;
- }
-
- // now, get the generic type of the enumerable
- var genericTypeOfArray = GetIListType(typeOfPathProperty);
- var conversionResult = ConvertToActualType(genericTypeOfArray, value);
- if (!conversionResult.CanBeConverted)
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatInvalidValueForProperty(value, path)));
- return;
- }
-
- // get value (it can be cast, we just checked that)
- var array = treeAnalysisResult.Container.GetValueForCaseInsensitiveKey(
- treeAnalysisResult.PropertyPathInParent) as IList;
-
- if (appendList)
- {
- array.Add(conversionResult.ConvertedInstance);
- treeAnalysisResult.Container.SetValueForCaseInsensitiveKey(
- treeAnalysisResult.PropertyPathInParent, array);
- }
- else
- {
- // specified index must not be greater than
- // the amount of items in the array
- if (positionAsInteger > array.Count)
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatInvalidIndexForArrayProperty(
- operationToReport.op,
- path)));
- return;
- }
-
- array.Insert(positionAsInteger, conversionResult.ConvertedInstance);
- treeAnalysisResult.Container.SetValueForCaseInsensitiveKey(
- treeAnalysisResult.PropertyPathInParent, array);
- }
- }
- else
- {
- // get the actual type
- var typeOfPathProperty = treeAnalysisResult.Container
- .GetValueForCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent).GetType();
-
- // can the value be converted to the actual type?
- var conversionResult = ConvertToActualType(typeOfPathProperty, value);
- if (conversionResult.CanBeConverted)
- {
- treeAnalysisResult.Container.SetValueForCaseInsensitiveKey(
- treeAnalysisResult.PropertyPathInParent,
- conversionResult.ConvertedInstance);
- }
- else
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatInvalidValueForProperty(conversionResult.ConvertedInstance, path)));
- return;
- }
- }
- }
- else
- {
- // New property - add it.
- treeAnalysisResult.Container.Add(treeAnalysisResult.PropertyPathInParent, value);
- }
- }
- else
- {
- // If it's an array, add to that array. If it's not, we replace.
-
- // is the path an array (but not a string (= char[]))? In this case,
- // the path must end with "/position" or "/-", which we already determined before.
-
- var patchProperty = treeAnalysisResult.JsonPatchProperty;
-
- if (appendList || positionAsInteger > -1)
- {
- if (!IsNonStringArray(patchProperty.Property.PropertyType))
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path)));
- return;
- }
-
- // now, get the generic type of the IList<> from Property type.
- var genericTypeOfArray = GetIListType(patchProperty.Property.PropertyType);
- var conversionResult = ConvertToActualType(genericTypeOfArray, value);
- if (!conversionResult.CanBeConverted)
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatInvalidValueForProperty(conversionResult.ConvertedInstance, path)));
- return;
- }
-
- if (!patchProperty.Property.Readable)
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatCannotReadProperty(path)));
- return;
- }
-
- var array = (IList)patchProperty.Property.ValueProvider.GetValue(patchProperty.Parent);
- if (appendList)
- {
- array.Add(conversionResult.ConvertedInstance);
- }
- else if (positionAsInteger <= array.Count)
- {
- array.Insert(positionAsInteger, conversionResult.ConvertedInstance);
- }
- else
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path)));
- return;
- }
- }
- else
- {
- var conversionResultTuple = ConvertToActualType(
- patchProperty.Property.PropertyType,
- value);
-
- if (!conversionResultTuple.CanBeConverted)
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatInvalidValueForProperty(value, path)));
- return;
- }
-
- if (!patchProperty.Property.Writable)
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatCannotUpdateProperty(path)));
- return;
- }
-
- patchProperty.Property.ValueProvider.SetValue(
- patchProperty.Parent,
- conversionResultTuple.ConvertedInstance);
- }
- }
- }
-
- ///
- /// The "move" operation removes the value at a specified location and
- /// adds it to the target location.
- ///
- /// The operation object MUST contain a "from" member, which is a string
- /// containing a JSON Pointer value that references the location in the
- /// target document to move the value from.
- ///
- /// The "from" location MUST exist for the operation to be successful.
- ///
- /// For example:
- ///
- /// { "op": "move", "from": "/a/b/c", "path": "/a/b/d" }
- ///
- /// This operation is functionally identical to a "remove" operation on
- /// the "from" location, followed immediately by an "add" operation at
- /// the target location with the value that was just removed.
- ///
- /// The "from" location MUST NOT be a proper prefix of the "path"
- /// location; i.e., a location cannot be moved into one of its children.
- ///
- /// The move operation.
- /// Object to apply the operation to.
- public void Move(Operation operation, object objectToApplyTo)
- {
- if (operation == null)
- {
- throw new ArgumentNullException(nameof(operation));
- }
-
- if (objectToApplyTo == null)
- {
- throw new ArgumentNullException(nameof(objectToApplyTo));
- }
-
- var valueAtFromLocationResult = GetValueAtLocation(operation.from, objectToApplyTo, operation);
-
- if (valueAtFromLocationResult.HasError)
- {
- // Error has already been logged in GetValueAtLocation. We
- // must return, because remove / add should not be allowed to continue
- return;
- }
-
- // remove that value
- var removeResult = Remove(operation.from, objectToApplyTo, operation);
-
- if (removeResult.HasError)
- {
- // Return => error has already been logged in remove method. We must
- // return, because add should not be allowed to continue
- return;
- }
-
- // add that value to the path location
- Add(operation.path,
- valueAtFromLocationResult.PropertyValue,
- objectToApplyTo,
- operation);
- }
-
- ///
- /// The "remove" operation removes the value at the target location.
- ///
- /// The target location MUST exist for the operation to be successful.
- ///
- /// For example:
- ///
- /// { "op": "remove", "path": "/a/b/c" }
- ///
- /// If removing an element from an array, any elements above the
- /// specified index are shifted one position to the left.
- ///
- /// The remove operation.
- /// Object to apply the operation to.
- public void Remove(Operation operation, object objectToApplyTo)
- {
- if (operation == null)
- {
- throw new ArgumentNullException(nameof(operation));
- }
-
- if (objectToApplyTo == null)
- {
- throw new ArgumentNullException(nameof(objectToApplyTo));
- }
-
- Remove(operation.path, objectToApplyTo, operation);
- }
-
-
- ///
- /// Remove is used by various operations (eg: remove, move, ...), yet through different operations;
- /// This method allows code reuse yet reporting the correct operation on error. The return value
- /// contains the type of the item that has been removed (and a bool possibly signifying an error)
- /// This can be used by other methods, like replace, to ensure that we can pass in the correctly
- /// typed value to whatever method follows.
- ///
- private RemovedPropertyTypeResult Remove(string path, object objectToApplyTo, Operation operationToReport)
- {
- // get path result
- var pathResult = GetActualPropertyPath(
- path,
- objectToApplyTo,
- operationToReport);
-
- if (pathResult == null)
- {
- return new RemovedPropertyTypeResult(null, true);
- }
-
- var removeFromList = pathResult.ExecuteAtEnd;
- var positionAsInteger = pathResult.NumericEnd;
- var actualPathToProperty = pathResult.PathToProperty;
-
- var treeAnalysisResult = new ObjectTreeAnalysisResult(
- objectToApplyTo,
- actualPathToProperty,
- ContractResolver);
-
- if (!treeAnalysisResult.IsValidPathForRemove)
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatPropertyCannotBeRemoved(path)));
- return new RemovedPropertyTypeResult(null, true);
- }
-
- if (treeAnalysisResult.UseDynamicLogic)
- {
- // if it's not an array, we can remove the property from
- // the dictionary. If it's an array, we need to check the position first.
- if (removeFromList || positionAsInteger > -1)
- {
- var propertyValue = treeAnalysisResult.Container
- .GetValueForCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent);
-
- // we cannot continue when the value is null, because to be able to
- // continue we need to be able to check if the array is a non-string array
- if (propertyValue == null)
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatCannotDeterminePropertyType(path)));
- return new RemovedPropertyTypeResult(null, true);
- }
-
- var typeOfPathProperty = propertyValue.GetType();
-
- if (!IsNonStringArray(typeOfPathProperty))
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path)));
- return new RemovedPropertyTypeResult(null, true);
- }
-
- // now, get the generic type of the enumerable (we'll return this type)
- var genericTypeOfArray = GetIListType(typeOfPathProperty);
-
- // get the array
- var array = (IList)treeAnalysisResult.Container.GetValueForCaseInsensitiveKey(
- treeAnalysisResult.PropertyPathInParent);
-
- if (array.Count == 0)
- {
- // if the array is empty, we should throw an error
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatInvalidIndexForArrayProperty(
- operationToReport.op,
- path)));
- return new RemovedPropertyTypeResult(null, true);
- }
-
- if (removeFromList)
- {
- array.RemoveAt(array.Count - 1);
- treeAnalysisResult.Container.SetValueForCaseInsensitiveKey(
- treeAnalysisResult.PropertyPathInParent, array);
-
- // return the type of the value that has been removed.
- return new RemovedPropertyTypeResult(genericTypeOfArray, false);
- }
- else
- {
- if (positionAsInteger >= array.Count)
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatInvalidIndexForArrayProperty(
- operationToReport.op,
- path)));
- return new RemovedPropertyTypeResult(null, true);
- }
-
- array.RemoveAt(positionAsInteger);
- treeAnalysisResult.Container.SetValueForCaseInsensitiveKey(
- treeAnalysisResult.PropertyPathInParent, array);
-
- // return the type of the value that has been removed.
- return new RemovedPropertyTypeResult(genericTypeOfArray, false);
- }
- }
- else
- {
- // get the property
- var getResult = treeAnalysisResult.Container.GetValueForCaseInsensitiveKey(
- treeAnalysisResult.PropertyPathInParent);
-
- // remove the property
- treeAnalysisResult.Container.RemoveValueForCaseInsensitiveKey(
- treeAnalysisResult.PropertyPathInParent);
-
- // value is not null, we can determine the type
- if (getResult != null)
- {
- var actualType = getResult.GetType();
- return new RemovedPropertyTypeResult(actualType, false);
- }
- else
- {
- return new RemovedPropertyTypeResult(null, false);
- }
- }
- }
- else
- {
- // not dynamic
- var patchProperty = treeAnalysisResult.JsonPatchProperty;
-
- if (removeFromList || positionAsInteger > -1)
- {
- if (!IsNonStringArray(patchProperty.Property.PropertyType))
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path)));
- return new RemovedPropertyTypeResult(null, true);
- }
-
- // now, get the generic type of the IList<> from Property type.
- var genericTypeOfArray = GetIListType(patchProperty.Property.PropertyType);
-
- if (!patchProperty.Property.Readable)
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatCannotReadProperty(path)));
- return new RemovedPropertyTypeResult(null, true);
- }
-
- var array = (IList)patchProperty.Property.ValueProvider
- .GetValue(patchProperty.Parent);
-
- if (array.Count == 0)
- {
- // if the array is empty, we should throw an error
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatInvalidIndexForArrayProperty(
- operationToReport.op,
- path)));
- return new RemovedPropertyTypeResult(null, true);
- }
-
- if (removeFromList)
- {
- array.RemoveAt(array.Count - 1);
-
- // return the type of the value that has been removed
- return new RemovedPropertyTypeResult(genericTypeOfArray, false);
- }
- else
- {
- if (positionAsInteger >= array.Count)
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatInvalidIndexForArrayProperty(
- operationToReport.op,
- path)));
- return new RemovedPropertyTypeResult(null, true);
- }
-
- array.RemoveAt(positionAsInteger);
-
- // return the type of the value that has been removed
- return new RemovedPropertyTypeResult(genericTypeOfArray, false);
- }
- }
- else
- {
- if (!patchProperty.Property.Writable)
- {
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatCannotUpdateProperty(path)));
- return new RemovedPropertyTypeResult(null, true);
- }
-
- // setting the value to "null" will use the default value in case of value types, and
- // null in case of reference types
- object value = null;
-
- if (patchProperty.Property.PropertyType.GetTypeInfo().IsValueType
- && Nullable.GetUnderlyingType(patchProperty.Property.PropertyType) == null)
- {
- value = Activator.CreateInstance(patchProperty.Property.PropertyType);
- }
-
- patchProperty.Property.ValueProvider.SetValue(patchProperty.Parent, value);
- return new RemovedPropertyTypeResult(patchProperty.Property.PropertyType, false);
- }
- }
- }
-
- ///
- /// The "replace" operation replaces the value at the target location
- /// with a new value. The operation object MUST contain a "value" member
- /// whose content specifies the replacement value.
- ///
- /// The target location MUST exist for the operation to be successful.
- ///
- /// For example:
- ///
- /// { "op": "replace", "path": "/a/b/c", "value": 42 }
- ///
- /// This operation is functionally identical to a "remove" operation for
- /// a value, followed immediately by an "add" operation at the same
- /// location with the replacement value.
- ///
- /// Note: even though it's the same functionally, we do not call remove + add
- /// for performance reasons (multiple checks of same requirements).
- ///
- /// The replace operation.
- /// Object to apply the operation to.
- public void Replace(Operation operation, object objectToApplyTo)
- {
- if (operation == null)
- {
- throw new ArgumentNullException(nameof(operation));
- }
-
- if (objectToApplyTo == null)
- {
- throw new ArgumentNullException(nameof(objectToApplyTo));
- }
-
- var removeResult = Remove(operation.path, objectToApplyTo, operation);
-
- if (removeResult.HasError)
- {
- // return => error has already been logged in remove method
- return;
- }
-
- if (!removeResult.HasError && removeResult.ActualType == null)
- {
- // the remove operation completed succesfully, but we could not determine the type.
- LogError(new JsonPatchError(
- objectToApplyTo,
- operation,
- Resources.FormatCannotDeterminePropertyType(operation.from)));
- return;
- }
-
- var conversionResult = ConvertToActualType(removeResult.ActualType, operation.value);
-
- if (!conversionResult.CanBeConverted)
- {
- // invalid value for path
- LogError(new JsonPatchError(
- objectToApplyTo,
- operation,
- Resources.FormatInvalidValueForProperty(operation.value, operation.path)));
- return;
- }
-
- Add(operation.path, conversionResult.ConvertedInstance, objectToApplyTo, operation);
- }
-
- ///
- /// The "copy" operation copies the value at a specified location to the
- /// target location.
- ///
- /// The operation object MUST contain a "from" member, which is a string
- /// containing a JSON Pointer value that references the location in the
- /// target document to copy the value from.
- ///
- /// The "from" location MUST exist for the operation to be successful.
- ///
- /// For example:
- ///
- /// { "op": "copy", "from": "/a/b/c", "path": "/a/b/e" }
- ///
- /// This operation is functionally identical to an "add" operation at the
- /// target location using the value specified in the "from" member.
- ///
- /// Note: even though it's the same functionally, we do not call add with
- /// the value specified in from for performance reasons (multiple checks of same requirements).
- ///
- /// The copy operation.
- /// Object to apply the operation to.
- public void Copy(Operation operation, object objectToApplyTo)
- {
- if (operation == null)
- {
- throw new ArgumentNullException(nameof(operation));
- }
-
- if (objectToApplyTo == null)
- {
- throw new ArgumentNullException(nameof(objectToApplyTo));
- }
-
- // get value at from location and add that value to the path location
- var valueAtFromLocationResult = GetValueAtLocation(operation.from, objectToApplyTo, operation);
-
- if (valueAtFromLocationResult.HasError)
- {
- // Return, error has already been logged in GetValueAtLocation
- return;
- }
-
- Add(operation.path,
- valueAtFromLocationResult.PropertyValue,
- objectToApplyTo,
- operation);
- }
-
- ///
- /// Method is used by Copy and Move to avoid duplicate code
- ///
- /// Location where value should be
- /// Object to inspect for the desired value
- /// Operation to report in case of an error
- /// GetValueResult containing value and a bool signifying a possible error
- private GetValueResult GetValueAtLocation(
- string location,
- object objectToGetValueFrom,
- Operation operationToReport)
- {
- if (location == null)
- {
- throw new ArgumentNullException(nameof(location));
- }
-
- if (objectToGetValueFrom == null)
- {
- throw new ArgumentNullException(nameof(objectToGetValueFrom));
- }
-
- if (operationToReport == null)
- {
- throw new ArgumentNullException(nameof(operationToReport));
- }
-
- // get path result
- var pathResult = GetActualPropertyPath(
- location,
- objectToGetValueFrom,
- operationToReport);
-
- if (pathResult == null)
- {
- return new GetValueResult(null, true);
- }
-
- var getAtEndOfList = pathResult.ExecuteAtEnd;
- var positionAsInteger = pathResult.NumericEnd;
- var actualPathToProperty = pathResult.PathToProperty;
-
- var treeAnalysisResult = new ObjectTreeAnalysisResult(
- objectToGetValueFrom,
- actualPathToProperty,
- ContractResolver);
-
- if (treeAnalysisResult.UseDynamicLogic)
- {
- // if it's not an array, we can remove the property from
- // the dictionary. If it's an array, we need to check the position first.
- if (getAtEndOfList || positionAsInteger > -1)
- {
- var propertyValue = treeAnalysisResult.Container
- .GetValueForCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent);
-
- // we cannot continue when the value is null, because to be able to
- // continue we need to be able to check if the array is a non-string array
- if (propertyValue == null)
- {
- LogError(new JsonPatchError(
- objectToGetValueFrom,
- operationToReport,
- Resources.FormatCannotDeterminePropertyType(location)));
- return new GetValueResult(null, true);
- }
-
- var typeOfPathProperty = propertyValue.GetType();
-
- if (!IsNonStringArray(typeOfPathProperty))
- {
- LogError(new JsonPatchError(
- objectToGetValueFrom,
- operationToReport,
- Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, location)));
- return new GetValueResult(null, true);
- }
-
- // get the array
- var array = (IList)treeAnalysisResult.Container.GetValueForCaseInsensitiveKey(
- treeAnalysisResult.PropertyPathInParent);
-
- if (positionAsInteger >= array.Count)
- {
- LogError(new JsonPatchError(
- objectToGetValueFrom,
- operationToReport,
- Resources.FormatInvalidIndexForArrayProperty(
- operationToReport.op,
- location)));
- return new GetValueResult(null, true);
- }
-
- if (getAtEndOfList)
- {
- return new GetValueResult(array[array.Count - 1], false);
- }
- else
- {
- return new GetValueResult(array[positionAsInteger], false);
- }
- }
- else
- {
- // get the property
- var propertyValueAtLocation = treeAnalysisResult.Container.GetValueForCaseInsensitiveKey(
- treeAnalysisResult.PropertyPathInParent);
-
- return new GetValueResult(propertyValueAtLocation, false);
- }
- }
- else
- {
- // not dynamic
- var patchProperty = treeAnalysisResult.JsonPatchProperty;
-
- if (getAtEndOfList || positionAsInteger > -1)
- {
- if (!IsNonStringArray(patchProperty.Property.PropertyType))
- {
- LogError(new JsonPatchError(
- objectToGetValueFrom,
- operationToReport,
- Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, location)));
- return new GetValueResult(null, true);
- }
-
- if (!patchProperty.Property.Readable)
- {
- LogError(new JsonPatchError(
- objectToGetValueFrom,
- operationToReport,
- Resources.FormatCannotReadProperty(location)));
- return new GetValueResult(null, true);
- }
-
- var array = (IList)patchProperty.Property.ValueProvider
- .GetValue(patchProperty.Parent);
-
- if (positionAsInteger >= array.Count)
- {
- LogError(new JsonPatchError(
- objectToGetValueFrom,
- operationToReport,
- Resources.FormatInvalidIndexForArrayProperty(
- operationToReport.op,
- location)));
- return new GetValueResult(null, true);
- }
-
- if (getAtEndOfList)
- {
- return new GetValueResult(array[array.Count - 1], false);
- }
- else
- {
- return new GetValueResult(array[positionAsInteger], false);
- }
- }
- else
- {
- if (!patchProperty.Property.Readable)
- {
- LogError(new JsonPatchError(
- objectToGetValueFrom,
- operationToReport,
- Resources.FormatCannotReadProperty(
- location)));
- return new GetValueResult(null, true);
- }
-
- var propertyValueAtLocation = patchProperty.Property.ValueProvider
- .GetValue(patchProperty.Parent);
-
- return new GetValueResult(propertyValueAtLocation, false);
- }
- }
- }
-
- private bool IsNonStringArray(Type type)
- {
- if (GetIListType(type) != null)
- {
- return true;
- }
-
- return (!(type == typeof(string)) && typeof(IList).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()));
- }
-
- private void LogError(JsonPatchError jsonPatchError)
- {
- if (LogErrorAction != null)
- {
- LogErrorAction(jsonPatchError);
- }
- else
- {
- throw new JsonPatchException(jsonPatchError);
- }
- }
-
- private ConversionResult ConvertToActualType(Type propertyType, object value)
- {
- try
- {
- var o = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(value), propertyType);
-
- return new ConversionResult(true, o);
- }
- catch (Exception)
- {
- return new ConversionResult(false, null);
- }
- }
-
- private Type GetIListType(Type type)
- {
- if (IsGenericListType(type))
- {
- return type.GetGenericArguments()[0];
- }
-
- foreach (Type interfaceType in type.GetTypeInfo().ImplementedInterfaces)
- {
- if (IsGenericListType(interfaceType))
- {
- return interfaceType.GetGenericArguments()[0];
- }
- }
-
- return null;
- }
-
- private bool IsGenericListType(Type type)
- {
- if (type.GetTypeInfo().IsGenericType &&
- type.GetGenericTypeDefinition() == typeof(IList<>))
- {
- return true;
- }
-
- return false;
- }
-
- private ActualPropertyPathResult GetActualPropertyPath(
- string propertyPath,
- object objectToApplyTo,
- Operation operationToReport)
- {
- if (propertyPath == null)
- {
- throw new ArgumentNullException(nameof(propertyPath));
- }
-
- if (objectToApplyTo == null)
- {
- throw new ArgumentNullException(nameof(objectToApplyTo));
- }
-
- if (operationToReport == null)
- {
- throw new ArgumentNullException(nameof(operationToReport));
- }
-
- if (propertyPath.EndsWith("/-"))
- {
- return new ActualPropertyPathResult(-1, propertyPath.Substring(0, propertyPath.Length - 2), true);
- }
- else
- {
- var possibleIndex = propertyPath.Substring(propertyPath.LastIndexOf("/") + 1);
- int castedIndex = -1;
- if (int.TryParse(possibleIndex, out castedIndex))
- {
- // has numeric end.
- if (castedIndex > -1)
- {
- var pathToProperty = propertyPath.Substring(
- 0,
- propertyPath.LastIndexOf('/' + castedIndex.ToString()));
-
- return new ActualPropertyPathResult(castedIndex, pathToProperty, false);
- }
- else
- {
- // negative position - invalid path
- LogError(new JsonPatchError(
- objectToApplyTo,
- operationToReport,
- Resources.FormatNegativeIndexForArrayProperty(operationToReport.op, propertyPath)));
- return null;
- }
- }
-
- return new ActualPropertyPathResult(-1, propertyPath, false);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.JsonPatch/Converters/JsonPatchDocumentConverter.cs b/src/Microsoft.AspNet.JsonPatch/Converters/JsonPatchDocumentConverter.cs
deleted file mode 100644
index 4551f64043..0000000000
--- a/src/Microsoft.AspNet.JsonPatch/Converters/JsonPatchDocumentConverter.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Generic;
-using Microsoft.AspNet.JsonPatch.Exceptions;
-using Microsoft.AspNet.JsonPatch.Operations;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using Newtonsoft.Json.Serialization;
-
-namespace Microsoft.AspNet.JsonPatch.Converters
-{
- public class JsonPatchDocumentConverter : JsonConverter
- {
- public override bool CanConvert(Type objectType)
- {
- return true;
- }
-
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
- JsonSerializer serializer)
- {
- if (objectType != typeof(JsonPatchDocument))
- {
- throw new ArgumentException(Resources.FormatParameterMustMatchType("objectType", "JsonPatchDocument"), "objectType");
- }
-
- try
- {
- if (reader.TokenType == JsonToken.Null)
- {
- return null;
- }
-
- // load jObject
- var jObject = JArray.Load(reader);
-
- // Create target object for Json => list of operations
- var targetOperations = new List();
-
- // Create a new reader for this jObject, and set all properties
- // to match the original reader.
- var jObjectReader = jObject.CreateReader();
- jObjectReader.Culture = reader.Culture;
- jObjectReader.DateParseHandling = reader.DateParseHandling;
- jObjectReader.DateTimeZoneHandling = reader.DateTimeZoneHandling;
- jObjectReader.FloatParseHandling = reader.FloatParseHandling;
-
- // Populate the object properties
- serializer.Populate(jObjectReader, targetOperations);
-
- // container target: the JsonPatchDocument.
- var container = new JsonPatchDocument(targetOperations, new DefaultContractResolver());
-
- return container;
- }
- catch (Exception ex)
- {
- throw new JsonPatchException(Resources.FormatInvalidJsonPatchDocument(objectType.Name), ex);
- }
- }
-
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
- {
- if (value is IJsonPatchDocument)
- {
- var jsonPatchDoc = (IJsonPatchDocument)value;
- var lst = jsonPatchDoc.GetOperations();
-
- // write out the operations, no envelope
- serializer.Serialize(writer, lst);
- }
- }
- }
-}
diff --git a/src/Microsoft.AspNet.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs b/src/Microsoft.AspNet.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs
deleted file mode 100644
index 7b6bb77e17..0000000000
--- a/src/Microsoft.AspNet.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using Microsoft.AspNet.JsonPatch.Exceptions;
-using Microsoft.AspNet.JsonPatch.Operations;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using Newtonsoft.Json.Serialization;
-
-namespace Microsoft.AspNet.JsonPatch.Converters
-{
- public class TypedJsonPatchDocumentConverter : JsonPatchDocumentConverter
- {
- public override object ReadJson(
- JsonReader reader,
- Type objectType,
- object existingValue,
- JsonSerializer serializer)
- {
- try
- {
- if (reader.TokenType == JsonToken.Null)
- {
- return null;
- }
-
- var genericType = objectType.GetGenericArguments()[0];
-
- // load jObject
- var jObject = JArray.Load(reader);
-
- // Create target object for Json => list of operations, typed to genericType
- var genericOperation = typeof(Operation<>);
- var concreteOperationType = genericOperation.MakeGenericType(genericType);
-
- var genericList = typeof(List<>);
- var concreteList = genericList.MakeGenericType(concreteOperationType);
-
- var targetOperations = Activator.CreateInstance(concreteList);
-
- //Create a new reader for this jObject, and set all properties to match the original reader.
- var jObjectReader = jObject.CreateReader();
- jObjectReader.Culture = reader.Culture;
- jObjectReader.DateParseHandling = reader.DateParseHandling;
- jObjectReader.DateTimeZoneHandling = reader.DateTimeZoneHandling;
- jObjectReader.FloatParseHandling = reader.FloatParseHandling;
-
- // Populate the object properties
- serializer.Populate(jObjectReader, targetOperations);
-
- // container target: the typed JsonPatchDocument.
- var container = Activator.CreateInstance(objectType, targetOperations, new DefaultContractResolver());
-
- return container;
- }
- catch (Exception ex)
- {
- throw new JsonPatchException(Resources.FormatInvalidJsonPatchDocument(objectType.Name), ex);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.JsonPatch/Exceptions/JsonPatchException.cs b/src/Microsoft.AspNet.JsonPatch/Exceptions/JsonPatchException.cs
deleted file mode 100644
index ac5222a2bb..0000000000
--- a/src/Microsoft.AspNet.JsonPatch/Exceptions/JsonPatchException.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using Microsoft.AspNet.JsonPatch.Operations;
-
-namespace Microsoft.AspNet.JsonPatch.Exceptions
-{
- public class JsonPatchException : Exception
- {
- public Operation FailedOperation { get; private set; }
- public object AffectedObject { get; private set; }
-
-
- public JsonPatchException()
- {
-
- }
-
- public JsonPatchException(JsonPatchError jsonPatchError, Exception innerException)
- : base(jsonPatchError.ErrorMessage, innerException)
- {
- FailedOperation = jsonPatchError.Operation;
- AffectedObject = jsonPatchError.AffectedObject;
- }
-
- public JsonPatchException(JsonPatchError jsonPatchError)
- : this(jsonPatchError, null)
- {
- }
-
- public JsonPatchException(string message, Exception innerException)
- : base (message, innerException)
- {
-
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/ActualPropertyPathResult.cs b/src/Microsoft.AspNet.JsonPatch/Helpers/ActualPropertyPathResult.cs
deleted file mode 100644
index d22d1bf830..0000000000
--- a/src/Microsoft.AspNet.JsonPatch/Helpers/ActualPropertyPathResult.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-namespace Microsoft.AspNet.JsonPatch.Helpers
-{
- internal class ActualPropertyPathResult
- {
- public int NumericEnd { get; private set; }
- public string PathToProperty { get; set; }
- public bool ExecuteAtEnd { get; set; }
-
- public ActualPropertyPathResult(
- int numericEnd,
- string pathToProperty,
- bool executeAtEnd)
- {
- NumericEnd = numericEnd;
- PathToProperty = pathToProperty;
- ExecuteAtEnd = executeAtEnd;
- }
- }
-}
diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/ConversionResult.cs b/src/Microsoft.AspNet.JsonPatch/Helpers/ConversionResult.cs
deleted file mode 100644
index aba4913f2d..0000000000
--- a/src/Microsoft.AspNet.JsonPatch/Helpers/ConversionResult.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-namespace Microsoft.AspNet.JsonPatch.Helpers
-{
- internal class ConversionResult
- {
- public bool CanBeConverted { get; private set; }
- public object ConvertedInstance { get; private set; }
-
- public ConversionResult(bool canBeConverted, object convertedInstance)
- {
- CanBeConverted = canBeConverted;
- ConvertedInstance = convertedInstance;
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs b/src/Microsoft.AspNet.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs
deleted file mode 100644
index a5911dded2..0000000000
--- a/src/Microsoft.AspNet.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Generic;
-
-namespace Microsoft.AspNet.JsonPatch.Helpers
-{
- // Helper methods to allow case-insensitive key search
- internal static class ExpandoObjectDictionaryExtensions
- {
- internal static void SetValueForCaseInsensitiveKey(
- this IDictionary propertyDictionary,
- string key,
- object value)
- {
- foreach (KeyValuePair kvp in propertyDictionary)
- {
- if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase))
- {
- propertyDictionary[kvp.Key] = value;
- break;
- }
- }
- }
-
- internal static void RemoveValueForCaseInsensitiveKey(
- this IDictionary propertyDictionary,
- string key)
- {
- string realKey = null;
- foreach (KeyValuePair kvp in propertyDictionary)
- {
- if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase))
- {
- realKey = kvp.Key;
- break;
- }
- }
-
- if (realKey != null)
- {
- propertyDictionary.Remove(realKey);
- }
- }
-
- internal static object GetValueForCaseInsensitiveKey(
- this IDictionary propertyDictionary,
- string key)
- {
- foreach (KeyValuePair kvp in propertyDictionary)
- {
- if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase))
- {
- return kvp.Value;
- }
- }
-
- throw new ArgumentException(Resources.FormatDictionaryKeyNotFound(key));
- }
-
- internal static bool ContainsCaseInsensitiveKey(
- this IDictionary propertyDictionary,
- string key)
- {
- foreach (KeyValuePair kvp in propertyDictionary)
- {
- if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase))
- {
- return true;
- }
- }
-
- return false;
- }
- }
-}
diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/ExpressionHelpers.cs b/src/Microsoft.AspNet.JsonPatch/Helpers/ExpressionHelpers.cs
deleted file mode 100644
index 6a0279876c..0000000000
--- a/src/Microsoft.AspNet.JsonPatch/Helpers/ExpressionHelpers.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Globalization;
-using System.Linq.Expressions;
-
-namespace Microsoft.AspNet.JsonPatch.Helpers
-{
- internal static class ExpressionHelpers
- {
- public static string GetPath(Expression> expr) where TModel : class
- {
- return "/" + GetPath(expr.Body, true);
- }
-
- private static string GetPath(Expression expr, bool firstTime)
- {
- switch (expr.NodeType)
- {
- case ExpressionType.ArrayIndex:
- var binaryExpression = (BinaryExpression)expr;
-
- if (ContinueWithSubPath(binaryExpression.Left.NodeType, false))
- {
- var leftFromBinaryExpression = GetPath(binaryExpression.Left, false);
- return leftFromBinaryExpression + "/" + binaryExpression.Right.ToString();
- }
- else
- {
- return binaryExpression.Right.ToString();
- }
- case ExpressionType.Call:
- var methodCallExpression = (MethodCallExpression)expr;
-
- if (ContinueWithSubPath(methodCallExpression.Object.NodeType, false))
- {
- var leftFromMemberCallExpression = GetPath(methodCallExpression.Object, false);
- return leftFromMemberCallExpression + "/" +
- GetIndexerInvocation(methodCallExpression.Arguments[0]);
- }
- else
- {
- return GetIndexerInvocation(methodCallExpression.Arguments[0]);
- }
- case ExpressionType.Convert:
- return GetPath(((UnaryExpression)expr).Operand, false);
- case ExpressionType.MemberAccess:
- var memberExpression = expr as MemberExpression;
-
- if (ContinueWithSubPath(memberExpression.Expression.NodeType, false))
- {
- var left = GetPath(memberExpression.Expression, false);
- return left + "/" + memberExpression.Member.Name;
- }
- else
- {
- return memberExpression.Member.Name;
- }
- case ExpressionType.Parameter:
- // Fits "x => x" (the whole document which is "" as JSON pointer)
- return firstTime ? string.Empty : null;
- default:
- return string.Empty;
- }
- }
-
- private static bool ContinueWithSubPath(ExpressionType expressionType, bool firstTime)
- {
- if (firstTime)
- {
- return (expressionType == ExpressionType.ArrayIndex
- || expressionType == ExpressionType.Call
- || expressionType == ExpressionType.Convert
- || expressionType == ExpressionType.MemberAccess
- || expressionType == ExpressionType.Parameter);
- }
- else
- {
- return (expressionType == ExpressionType.ArrayIndex
- || expressionType == ExpressionType.Call
- || expressionType == ExpressionType.Convert
- || expressionType == ExpressionType.MemberAccess);
- }
- }
-
- private static string GetIndexerInvocation(Expression expression)
- {
- var converted = Expression.Convert(expression, typeof(object));
- var fakeParameter = Expression.Parameter(typeof(object), null);
- var lambda = Expression.Lambda>(converted, fakeParameter);
- Func