diff --git a/src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicArray.cs b/src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicArray.cs index d975d859e65..cee0d2fd1f9 100644 --- a/src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicArray.cs +++ b/src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicArray.cs @@ -41,6 +41,20 @@ public object? this[int index] } } + public bool Remove(JsonNode? item) + { + var index = _jsonArray.IndexOf(item); + _dictionary.Remove(index); + + return _jsonArray.Remove(item); + } + + public void RemoveAt(int index) + { + _dictionary.Remove(index); + _jsonArray.RemoveAt(index); + } + public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object? result) { var value = GetValue((int)indexes[0]); diff --git a/src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicObject.cs b/src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicObject.cs index 15b374b6b25..9e4ea95cfc5 100644 --- a/src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicObject.cs +++ b/src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicObject.cs @@ -80,6 +80,18 @@ public override bool TryInvokeMember(InvokeMemberBinder binder, object?[]? args, return true; } + public bool Remove(string key) + { + _dictionary.Remove(key); + + return _jsonObject.Remove(key); + } + + public JsonNode? SelectNode(string path) => _jsonObject.SelectNode(path); + + [Obsolete("Please use the SelectNode method", error: true)] + public JsonNode? SelectToken(string path) => _jsonObject.SelectNode(path); + public object? GetValue(string key) { if (_dictionary.TryGetValue(key, out var value)) diff --git a/test/OrchardCore.Tests/Data/ContentItemTests.cs b/test/OrchardCore.Tests/Data/ContentItemTests.cs index c726513357d..860b260e025 100644 --- a/test/OrchardCore.Tests/Data/ContentItemTests.cs +++ b/test/OrchardCore.Tests/Data/ContentItemTests.cs @@ -1,6 +1,7 @@ using System.Text.Json; -using OrchardCore.ContentManagement; +using System.Text.Json.Dynamic; using System.Text.Json.Nodes; +using OrchardCore.ContentManagement; namespace OrchardCore.Tests.Data { @@ -117,27 +118,34 @@ public void ContentShouldBeJsonPathQueryable() AssertJsonEqual(textPropertyNode, contentItemJson.SelectNode("$..Text")); } - private static ContentItem CreateContentItemWithMyPart(string text = "test") + [Fact] + public void RemovingPropertyShouldWork() { var contentItem = new ContentItem(); contentItem.GetOrCreate(); - contentItem.Alter(x => x.Text = text); - - return contentItem; + contentItem.Alter(x => x.Text = "test"); + + JsonDynamicObject content = contentItem.Content; + Assert.Null(content.GetValue("not real property")); // Properties that don't exist return null. + Assert.NotNull(content.GetValue(nameof(MyPart))); // Right now this property exists. + + content.Remove(nameof(MyPart)); + Assert.Null(content.GetValue(nameof(MyPart))); } - private static void AssertJsonEqual(JsonNode expected, JsonNode actual) + [Fact] + public void ContentShouldCanCallRemoveMethod() { - Assert.NotNull(expected); - Assert.NotNull(actual); - Assert.Equal(expected.ToJsonString(), actual.ToJsonString()); + var contentItem = CreateContentItemWithMyPart(); + contentItem.Alter(x => x.Text = "test"); + Assert.Equal("test", contentItem.As().Text); + Assert.True(contentItem.Content.Remove("MyPart")); } [Fact] public void ShouldDeserializeListContentPart() { - var contentItem = new ContentItem(); - contentItem.GetOrCreate(); + var contentItem = CreateContentItemWithMyPart(); contentItem.Alter(x => x.Text = "test"); contentItem.Alter(x => { @@ -149,6 +157,22 @@ public void ShouldDeserializeListContentPart() Assert.Contains(@"""MyPart"":{""Text"":""test"",""myField"":{""Value"":123}}", json); } + + private static ContentItem CreateContentItemWithMyPart(string text = "test") + { + var contentItem = new ContentItem(); + contentItem.GetOrCreate(); + contentItem.Alter(x => x.Text = text); + + return contentItem; + } + + private static void AssertJsonEqual(JsonNode expected, JsonNode actual) + { + Assert.NotNull(expected); + Assert.NotNull(actual); + Assert.Equal(expected.ToJsonString(), actual.ToJsonString()); + } } public class MyPart : ContentPart