-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Added System.Text.Json serialization-based JsonPatch implementation #61313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
7483c60
Added S.T.J-serialization based JsonPatch
mkArtakMSFT 0dcb4a6
Cleanup + a few bugfixes
mkArtakMSFT 00fe861
Address review feedback
mkArtakMSFT 840e130
- Adopt the converter implementation provided by the S.T.J owner team
mkArtakMSFT 32e451f
Optimizations based on review from the Json team
mkArtakMSFT 70dcae7
Addressed review feedback
mkArtakMSFT f8483ff
Added a unit test to validate that JsonNamingPolicy is taking into co…
mkArtakMSFT File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"version": "1.0", | ||
"components": [ | ||
"Microsoft.Net.Component.4.6.2.TargetingPack", | ||
"Microsoft.Net.Component.4.7.2.SDK", | ||
"Microsoft.Net.Component.4.7.2.TargetingPack", | ||
"Microsoft.VisualStudio.Workload.ManagedDesktop", | ||
"Microsoft.VisualStudio.Workload.NetCoreTools", | ||
"Microsoft.VisualStudio.Workload.NetWeb", | ||
"Microsoft.VisualStudio.Workload.VisualStudioExtension" | ||
] | ||
} |
9 changes: 9 additions & 0 deletions
9
src/Features/JsonPatch.SystemTextJson/JsonPatch.SystemTextJson.slnf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"solution": { | ||
"path": "..\\..\\..\\AspNetCore.slnx", | ||
"projects" : [ | ||
"src\\Features\\JsonPatch.SystemTextJson\\src\\Microsoft.AspNetCore.JsonPatch.SystemTextJson.csproj", | ||
"src\\Features\\JsonPatch.SystemTextJson\\test\\Microsoft.AspNetCore.JsonPatch.SystemTextJson.Tests.csproj" | ||
] | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
@ECHO OFF | ||
SET RepoRoot=%~dp0..\..\.. | ||
%RepoRoot%\eng\build.cmd -projects %~dp0**\*.*proj %* | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#!/usr/bin/env bash | ||
|
||
set -euo pipefail | ||
|
||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" | ||
repo_root="$DIR/../.." | ||
"$repo_root/eng/build.sh" --projects "$DIR/**/*.*proj" "$@" |
40 changes: 40 additions & 0 deletions
40
src/Features/JsonPatch.SystemTextJson/src/Adapters/AdapterFactory.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Text.Json.Nodes; | ||
using Microsoft.AspNetCore.JsonPatch.SystemTextJson.Internal; | ||
using Microsoft.AspNetCore.Shared; | ||
|
||
namespace Microsoft.AspNetCore.JsonPatch.SystemTextJson.Adapters; | ||
|
||
/// <summary> | ||
/// The default AdapterFactory to be used for resolving <see cref="IAdapter"/>. | ||
/// </summary> | ||
internal class AdapterFactory : IAdapterFactory | ||
{ | ||
internal static AdapterFactory Default { get; } = new(); | ||
|
||
/// <inheritdoc /> | ||
public virtual IAdapter Create(object target) | ||
{ | ||
ArgumentNullThrowHelper.ThrowIfNull(target); | ||
|
||
var typeToConvert = target.GetType(); | ||
if (typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(Dictionary<,>)) | ||
{ | ||
return (IAdapter)Activator.CreateInstance(typeof(DictionaryAdapter<,>).MakeGenericType(typeToConvert.GenericTypeArguments[0], typeToConvert.GenericTypeArguments[1])); | ||
} | ||
|
||
return target switch | ||
{ | ||
JsonObject => new JsonObjectAdapter(), | ||
JsonArray => new ListAdapter(), | ||
IList => new ListAdapter(), | ||
_ => new PocoAdapter() | ||
}; | ||
} | ||
} | ||
|
19 changes: 19 additions & 0 deletions
19
src/Features/JsonPatch.SystemTextJson/src/Adapters/IAdapterFactory.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using Microsoft.AspNetCore.JsonPatch.SystemTextJson.Internal; | ||
|
||
namespace Microsoft.AspNetCore.JsonPatch.SystemTextJson.Adapters; | ||
|
||
/// <summary> | ||
/// Defines the operations used for loading an <see cref="IAdapter"/> based on the current object and ContractResolver. | ||
/// </summary> | ||
public interface IAdapterFactory | ||
{ | ||
/// <summary> | ||
/// Creates an <see cref="IAdapter"/> for the current object | ||
/// </summary> | ||
/// <param name="target">The target object</param> | ||
/// <returns>The needed <see cref="IAdapter"/></returns> | ||
IAdapter Create(object target); | ||
} |
111 changes: 111 additions & 0 deletions
111
src/Features/JsonPatch.SystemTextJson/src/Adapters/IObjectAdapter.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using Microsoft.AspNetCore.JsonPatch.SystemTextJson.Operations; | ||
|
||
namespace Microsoft.AspNetCore.JsonPatch.SystemTextJson.Adapters; | ||
|
||
/// <summary> | ||
/// Defines the operations that can be performed on a JSON patch document. | ||
/// </summary> | ||
public interface IObjectAdapter | ||
{ | ||
/// <summary> | ||
/// Using the "add" operation a new value is inserted into the root of the target | ||
/// document, into the target array at the specified valid index, or to a target object at | ||
/// the specified location. | ||
/// | ||
/// When adding to arrays, the specified index MUST NOT be greater than the number of elements in the array. | ||
/// To append the value to the array, the index of "-" character is used (see [RFC6901]). | ||
/// | ||
/// When adding to an object, if an object member does not already exist, a new member is added to the object at the | ||
/// specified location or if an object member 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" ] } | ||
/// | ||
/// See RFC 6902 <see href="https://tools.ietf.org/html/rfc6902#page-4"/> | ||
/// </summary> | ||
/// <param name="operation">The add operation.</param> | ||
/// <param name="objectToApplyTo">Object to apply the operation to.</param> | ||
void Add(Operation operation, object objectToApplyTo); | ||
|
||
/// <summary> | ||
/// Using the "copy" operation, a value is copied from a specified location to the | ||
/// target location. | ||
/// | ||
/// The operation object MUST contain a "from" member, which 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" } | ||
/// | ||
/// See RFC 6902 <see href="https://tools.ietf.org/html/rfc6902#page-7"/> | ||
/// </summary> | ||
/// <param name="operation">The copy operation.</param> | ||
/// <param name="objectToApplyTo">Object to apply the operation to.</param> | ||
void Copy(Operation operation, object objectToApplyTo); | ||
|
||
/// <summary> | ||
/// Using the "move" operation the value at a specified location is removed and | ||
/// added to the target location. | ||
/// | ||
/// The operation object MUST contain a "from" member, which 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" } | ||
/// | ||
/// A location cannot be moved into one of its children. | ||
/// | ||
/// See RFC 6902 <see href="https://tools.ietf.org/html/rfc6902#page-6"/> | ||
/// </summary> | ||
/// <param name="operation">The move operation.</param> | ||
/// <param name="objectToApplyTo">Object to apply the operation to.</param> | ||
void Move(Operation operation, object objectToApplyTo); | ||
|
||
/// <summary> | ||
/// Using the "remove" operation the value at the target location is removed. | ||
/// | ||
/// 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. | ||
/// | ||
/// See RFC 6902 <see href="https://tools.ietf.org/html/rfc6902#page-6"/> | ||
/// </summary> | ||
/// <param name="operation">The remove operation.</param> | ||
/// <param name="objectToApplyTo">Object to apply the operation to.</param> | ||
void Remove(Operation operation, object objectToApplyTo); | ||
|
||
/// <summary> | ||
/// Using the "replace" operation the value at the target location is replaced | ||
/// with a new value. The operation object MUST contain a "value" member | ||
/// which 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 } | ||
/// | ||
/// See RFC 6902 <see href="https://tools.ietf.org/html/rfc6902#page-6"/> | ||
/// </summary> | ||
/// <param name="operation">The replace operation.</param> | ||
/// <param name="objectToApplyTo">Object to apply the operation to.</param> | ||
void Replace(Operation operation, object objectToApplyTo); | ||
} |
31 changes: 31 additions & 0 deletions
31
src/Features/JsonPatch.SystemTextJson/src/Adapters/IObjectAdapterWithTest.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using Microsoft.AspNetCore.JsonPatch.SystemTextJson.Operations; | ||
|
||
namespace Microsoft.AspNetCore.JsonPatch.SystemTextJson.Adapters; | ||
|
||
/// <summary> | ||
/// Defines the operations that can be performed on a JSON patch document, including "test". | ||
/// </summary> | ||
public interface IObjectAdapterWithTest : IObjectAdapter | ||
{ | ||
/// <summary> | ||
/// Using the "test" operation a value at the target location is compared for | ||
/// equality to a specified value. | ||
/// | ||
/// The operation object MUST contain a "value" member that specifies | ||
/// value to be compared to the target location's value. | ||
/// | ||
/// The target location MUST be equal to the "value" value for the | ||
/// operation to be considered successful. | ||
/// | ||
/// For example: | ||
/// { "op": "test", "path": "/a/b/c", "value": "foo" } | ||
/// | ||
/// See RFC 6902 <see href="https://tools.ietf.org/html/rfc6902#page-7"/> | ||
/// </summary> | ||
/// <param name="operation">The test operation.</param> | ||
/// <param name="objectToApplyTo">Object to apply the operation to.</param> | ||
void Test(Operation operation, object objectToApplyTo); | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.