From bd4d3a8541f334ad3caee478eb921fa1900fcc3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Thu, 22 Feb 2024 14:13:20 +0100 Subject: [PATCH 01/20] Update NuGet versions to pre-release. --- Lombiq.JsonEditor/Lombiq.JsonEditor.csproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj index 60421b9..2eaadf4 100644 --- a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj +++ b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj @@ -36,12 +36,12 @@ - - - - - - + + + + + + From 23120d2ab65b2e7bc7eb32fef3177fd3b380ac50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Fri, 23 Feb 2024 20:24:13 +0100 Subject: [PATCH 02/20] Fix compilation errors. --- Lombiq.JsonEditor/Settings/JsonFieldSettings.cs | 6 +++++- Lombiq.JsonEditor/Settings/JsonFieldSettingsDriver.cs | 5 +++-- Lombiq.JsonEditor/Views/JsonEditor.cshtml | 8 +------- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Lombiq.JsonEditor/Settings/JsonFieldSettings.cs b/Lombiq.JsonEditor/Settings/JsonFieldSettings.cs index f49bd67..50347e8 100644 --- a/Lombiq.JsonEditor/Settings/JsonFieldSettings.cs +++ b/Lombiq.JsonEditor/Settings/JsonFieldSettings.cs @@ -1,6 +1,10 @@ +using Lombiq.HelpfulLibraries.Common.Utilities; + namespace Lombiq.JsonEditor.Settings; -public class JsonFieldSettings +public class JsonFieldSettings : ICopier { public string JsonEditorOptions { get; set; } + + public void CopyTo(JsonFieldSettings target) => target.JsonEditorOptions = JsonEditorOptions; } diff --git a/Lombiq.JsonEditor/Settings/JsonFieldSettingsDriver.cs b/Lombiq.JsonEditor/Settings/JsonFieldSettingsDriver.cs index 4d5b3a4..3181c6b 100644 --- a/Lombiq.JsonEditor/Settings/JsonFieldSettingsDriver.cs +++ b/Lombiq.JsonEditor/Settings/JsonFieldSettingsDriver.cs @@ -2,6 +2,7 @@ using Lombiq.JsonEditor.Models; using Microsoft.Extensions.Localization; using Newtonsoft.Json; +using OrchardCore.ContentManagement.Metadata.Builders; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentTypes.Editors; using OrchardCore.DisplayManagement.Views; @@ -16,8 +17,8 @@ public class JsonFieldSettingsDriver : ContentPartFieldDefinitionDisplayDriver stringLocalizer) => T = stringLocalizer; public override IDisplayResult Edit(ContentPartFieldDefinition model) => - Initialize($"{nameof(JsonFieldSettings)}_Edit", model.PopulateSettings) - .Location("Content"); + Initialize($"{nameof(JsonFieldSettings)}_Edit", model.CopySettingsTo) + .PlaceInContent(); public override async Task UpdateAsync( ContentPartFieldDefinition model, diff --git a/Lombiq.JsonEditor/Views/JsonEditor.cshtml b/Lombiq.JsonEditor/Views/JsonEditor.cshtml index 5c90947..0a57a5d 100644 --- a/Lombiq.JsonEditor/Views/JsonEditor.cshtml +++ b/Lombiq.JsonEditor/Views/JsonEditor.cshtml @@ -19,12 +19,6 @@ var uniqueGuid = Guid.NewGuid(); var editorId = $"{editorName}_{uniqueGuid:N}"; var inputId = $"{inputName}_{uniqueGuid:N}"; - - var camelCase = new JsonSerializerSettings - { - ContractResolver = new DefaultContractResolver { NamingStrategy = new CamelCaseNamingStrategy() }, - Formatting = Formatting.Indented, - }; }
@@ -38,7 +32,7 @@ var $editor = $('#@editorId'); var $input = $('#@inputId'); - var options = @Json.Serialize(options, camelCase); + var options = @Json.Serialize(options); options.onChange = function () { try { From 0e09cc06b767d4d1e94b75c07c6a7ebb0e34a87a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Sat, 24 Feb 2024 02:05:27 +0100 Subject: [PATCH 03/20] Remove "using Newtonsoft.Json" --- .../Controllers/AdminController.cs | 6 +++--- .../Drivers/JsonFieldDisplayDriver.cs | 19 +++---------------- Lombiq.JsonEditor/Models/JsonEditorOptions.cs | 4 ++-- .../Settings/JsonFieldSettingsDriver.cs | 5 +++-- Lombiq.JsonEditor/Views/_ViewImports.cshtml | 6 +++--- 5 files changed, 14 insertions(+), 26 deletions(-) diff --git a/Lombiq.JsonEditor/Controllers/AdminController.cs b/Lombiq.JsonEditor/Controllers/AdminController.cs index 93235f7..22ee617 100644 --- a/Lombiq.JsonEditor/Controllers/AdminController.cs +++ b/Lombiq.JsonEditor/Controllers/AdminController.cs @@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Mvc.Localization; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.Extensions.Localization; -using Newtonsoft.Json; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Metadata; using OrchardCore.Contents; @@ -20,6 +19,7 @@ using OrchardCore.Title.ViewModels; using System; using System.Security.Claims; +using System.Text.Json; using System.Threading.Tasks; namespace Lombiq.JsonEditor.Controllers; @@ -78,7 +78,7 @@ await _contentManager.GetAsync(contentItemId, VersionOptions.Latest) is not { } await _layoutAccessor.AddShapeToZoneAsync("Title", titleShape); var definition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); - return View(new EditContentItemViewModel(contentItem, definition, JsonConvert.SerializeObject(contentItem))); + return View(new EditContentItemViewModel(contentItem, definition, JsonSerializer.Serialize(contentItem))); } [ValidateAntiForgeryToken] @@ -92,7 +92,7 @@ public async Task EditPost( { if (string.IsNullOrWhiteSpace(contentItemId) || string.IsNullOrWhiteSpace(json) || - JsonConvert.DeserializeObject(json) is not { } contentItem) + JsonSerializer.Deserialize(json) is not { } contentItem) { return NotFound(); } diff --git a/Lombiq.JsonEditor/Drivers/JsonFieldDisplayDriver.cs b/Lombiq.JsonEditor/Drivers/JsonFieldDisplayDriver.cs index 4ba1683..ce4df56 100644 --- a/Lombiq.JsonEditor/Drivers/JsonFieldDisplayDriver.cs +++ b/Lombiq.JsonEditor/Drivers/JsonFieldDisplayDriver.cs @@ -1,12 +1,12 @@ +using Lombiq.HelpfulLibraries.Common.Utilities; using Lombiq.JsonEditor.Fields; using Lombiq.JsonEditor.ViewModels; using Microsoft.Extensions.Localization; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using OrchardCore.ContentManagement.Display.ContentDisplay; using OrchardCore.ContentManagement.Display.Models; using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Views; +using System.Text.Json; using System.Threading.Tasks; namespace Lombiq.JsonEditor.Drivers; @@ -42,7 +42,7 @@ public override async Task UpdateAsync(JsonField field, IUpdateM if (!await updater.TryUpdateModelAsync(model, Prefix)) return await EditAsync(field, context); - if (!TryParse(model.Value)) + if (JsonHelpers.ValidateJsonIfNotNull(model.Value) == false) { updater.ModelState.AddModelError(Prefix, T["The input isn't a valid JSON entity."]); } @@ -53,17 +53,4 @@ public override async Task UpdateAsync(JsonField field, IUpdateM return await EditAsync(field, context); } - - private static bool TryParse(string value) - { - try - { - JObject.Parse(value); - return true; - } - catch (JsonException) - { - return false; - } - } } diff --git a/Lombiq.JsonEditor/Models/JsonEditorOptions.cs b/Lombiq.JsonEditor/Models/JsonEditorOptions.cs index 2a0df8d..c17d8c3 100644 --- a/Lombiq.JsonEditor/Models/JsonEditorOptions.cs +++ b/Lombiq.JsonEditor/Models/JsonEditorOptions.cs @@ -1,8 +1,8 @@ using Microsoft.AspNetCore.Mvc.Localization; -using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json.Serialization; namespace Lombiq.JsonEditor.Models; @@ -29,7 +29,7 @@ public class JsonEditorOptions /// public bool History { get; set; } = true; - [JsonProperty("mode")] + [JsonPropertyName("mode")] private string ModeString { get; set; } = "tree"; /// diff --git a/Lombiq.JsonEditor/Settings/JsonFieldSettingsDriver.cs b/Lombiq.JsonEditor/Settings/JsonFieldSettingsDriver.cs index 3181c6b..c1c17df 100644 --- a/Lombiq.JsonEditor/Settings/JsonFieldSettingsDriver.cs +++ b/Lombiq.JsonEditor/Settings/JsonFieldSettingsDriver.cs @@ -1,11 +1,12 @@ using Lombiq.JsonEditor.Fields; using Lombiq.JsonEditor.Models; using Microsoft.Extensions.Localization; -using Newtonsoft.Json; using OrchardCore.ContentManagement.Metadata.Builders; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentTypes.Editors; using OrchardCore.DisplayManagement.Views; +using System.Text.Json; +using System.Text.Json.Nodes; using System.Threading.Tasks; namespace Lombiq.JsonEditor.Settings; @@ -29,7 +30,7 @@ public override async Task UpdateAsync( try { - JsonConvert.DeserializeObject(settings.JsonEditorOptions); + JsonNode.Parse(settings.JsonEditorOptions).ToObject(); context.Builder.WithSettings(settings); } catch (JsonException) diff --git a/Lombiq.JsonEditor/Views/_ViewImports.cshtml b/Lombiq.JsonEditor/Views/_ViewImports.cshtml index 764e037..ca098ae 100644 --- a/Lombiq.JsonEditor/Views/_ViewImports.cshtml +++ b/Lombiq.JsonEditor/Views/_ViewImports.cshtml @@ -9,7 +9,7 @@ @using Lombiq.JsonEditor.Constants @using Lombiq.JsonEditor.Models @using Microsoft.AspNetCore.Mvc.Localization -@using Newtonsoft.Json -@using Newtonsoft.Json.Linq -@using Newtonsoft.Json.Serialization +@using System.Text.Json +@using System.Text.Json.Nodes +@using System.Text.Json.Serialization @using OrchardCore.Mvc.Core.Utilities From 4f0d04208591a0ef6bbe1a3d031bd71099de3e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Sat, 24 Feb 2024 13:16:45 +0100 Subject: [PATCH 04/20] Fix compilation errors. --- Lombiq.JsonEditor/Views/JsonEditor.cshtml | 20 +++++++++---------- Lombiq.JsonEditor/Views/JsonField.Edit.cshtml | 2 +- .../Views/JsonFieldSettings.Edit.cshtml | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Lombiq.JsonEditor/Views/JsonEditor.cshtml b/Lombiq.JsonEditor/Views/JsonEditor.cshtml index 0a57a5d..a8717a0 100644 --- a/Lombiq.JsonEditor/Views/JsonEditor.cshtml +++ b/Lombiq.JsonEditor/Views/JsonEditor.cshtml @@ -1,12 +1,12 @@ @{ var json = Model.Content switch { - JToken jToken => jToken, - { } someObject => JToken.FromObject(someObject), + JsonNode jsonNode => jsonNode, + { } someObject => JsonSerializer.SerializeToNode(someObject), null when Model.SerializedJson?.ToString() is string jsonString && !string.IsNullOrWhiteSpace(jsonString) => - JToken.Parse(jsonString), - _ => new JObject(), - }; + JsonNode.Parse(jsonString), + _ => null, + } ?? new JsonObject(); var options = Model.Options as JsonEditorOptions ?? new JsonEditorOptions(); var name = Model.InputName?.ToString() as string; @@ -29,10 +29,10 @@ From fc86fd86d3b471793774049bf23e200afb1b68bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Sun, 25 Feb 2024 13:47:34 +0100 Subject: [PATCH 06/20] unusing --- Lombiq.JsonEditor/Drivers/JsonFieldDisplayDriver.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Lombiq.JsonEditor/Drivers/JsonFieldDisplayDriver.cs b/Lombiq.JsonEditor/Drivers/JsonFieldDisplayDriver.cs index ce4df56..df02222 100644 --- a/Lombiq.JsonEditor/Drivers/JsonFieldDisplayDriver.cs +++ b/Lombiq.JsonEditor/Drivers/JsonFieldDisplayDriver.cs @@ -6,7 +6,6 @@ using OrchardCore.ContentManagement.Display.Models; using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Views; -using System.Text.Json; using System.Threading.Tasks; namespace Lombiq.JsonEditor.Drivers; From a27c336b84e4f0e5096340852246c11403a91b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Mon, 4 Mar 2024 00:22:18 +0100 Subject: [PATCH 07/20] Update OC to latest (because of bug fix for WorkflowTypeStep) --- Lombiq.JsonEditor/Lombiq.JsonEditor.csproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj index 63f78a0..627b18f 100644 --- a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj +++ b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj @@ -36,12 +36,12 @@ - - - - - - + + + + + + From 0f19df112f8f29c4e8025821974345fff0808d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Fri, 8 Mar 2024 00:09:19 +0100 Subject: [PATCH 08/20] Update OC preview version. --- Lombiq.JsonEditor/Lombiq.JsonEditor.csproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj index 627b18f..edb51d1 100644 --- a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj +++ b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj @@ -36,12 +36,12 @@ - - - - - - + + + + + + From cbc63b1b124dce9429c1adf6a663f0b13c71b0ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Wed, 13 Mar 2024 06:15:50 +0100 Subject: [PATCH 09/20] Update OC package --- Lombiq.JsonEditor/Lombiq.JsonEditor.csproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj index edb51d1..af3e41d 100644 --- a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj +++ b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj @@ -36,12 +36,12 @@ - - - - - - + + + + + + From c068c3770606ad2465981d0bb99290a9fddb2ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Mon, 18 Mar 2024 01:28:21 +0100 Subject: [PATCH 10/20] Replace AdminRouteAttribute with AdminAttribute. --- Lombiq.JsonEditor/Controllers/AdminController.cs | 4 ++-- Lombiq.JsonEditor/Startup.cs | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Lombiq.JsonEditor/Controllers/AdminController.cs b/Lombiq.JsonEditor/Controllers/AdminController.cs index 22ee617..509ed55 100644 --- a/Lombiq.JsonEditor/Controllers/AdminController.cs +++ b/Lombiq.JsonEditor/Controllers/AdminController.cs @@ -1,13 +1,13 @@ using AngleSharp.Common; using Lombiq.HelpfulLibraries.OrchardCore.Contents; using Lombiq.HelpfulLibraries.OrchardCore.DependencyInjection; -using Lombiq.HelpfulLibraries.OrchardCore.Mvc; using Lombiq.JsonEditor.ViewModels; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Localization; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.Extensions.Localization; +using OrchardCore.Admin; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Metadata; using OrchardCore.Contents; @@ -58,7 +58,7 @@ public AdminController( H = services.HtmlLocalizer.Value; } - [AdminRoute("Contents/ContentItems/{contentItemId}/Edit/Json")] + [Admin("Contents/ContentItems/{contentItemId}/Edit/Json")] public async Task Edit(string contentItemId) { if (string.IsNullOrWhiteSpace(contentItemId) || diff --git a/Lombiq.JsonEditor/Startup.cs b/Lombiq.JsonEditor/Startup.cs index 41ced1d..47c104f 100644 --- a/Lombiq.JsonEditor/Startup.cs +++ b/Lombiq.JsonEditor/Startup.cs @@ -1,5 +1,4 @@ using Lombiq.HelpfulLibraries.OrchardCore.DependencyInjection; -using Lombiq.HelpfulLibraries.OrchardCore.Mvc; using Lombiq.JsonEditor.Constants; using Lombiq.JsonEditor.Drivers; using Lombiq.JsonEditor.Fields; @@ -43,6 +42,5 @@ public override void ConfigureServices(IServiceCollection services) services.AddOrchardServices(); services.AddScoped(); services.AddContentSecurityPolicyProvider(); - AdminRouteAttributeRouteMapper.AddToServices(services); } } From 7b0bd5ac4faad3901148c6d7efb25e240665cc02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Tue, 2 Apr 2024 14:53:23 +0200 Subject: [PATCH 11/20] Use JObject.FromObject instead of JsonSerializer.SerializeToNode where applicable. --- Lombiq.JsonEditor/Views/JsonEditor.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lombiq.JsonEditor/Views/JsonEditor.cshtml b/Lombiq.JsonEditor/Views/JsonEditor.cshtml index a8717a0..8066eaf 100644 --- a/Lombiq.JsonEditor/Views/JsonEditor.cshtml +++ b/Lombiq.JsonEditor/Views/JsonEditor.cshtml @@ -2,7 +2,7 @@ var json = Model.Content switch { JsonNode jsonNode => jsonNode, - { } someObject => JsonSerializer.SerializeToNode(someObject), + object someObject => JObject.FromObject(someObject), null when Model.SerializedJson?.ToString() is string jsonString && !string.IsNullOrWhiteSpace(jsonString) => JsonNode.Parse(jsonString), _ => null, From 5d86e6224bb44b0c51873bb15b485262c68927a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Tue, 23 Apr 2024 17:17:30 +0200 Subject: [PATCH 12/20] Update OC preview version. --- Lombiq.JsonEditor/Lombiq.JsonEditor.csproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj index af3e41d..8783b92 100644 --- a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj +++ b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj @@ -36,12 +36,12 @@ - - - - - - + + + + + + From 346271e5bbe6bc51c45b08b6f243222c7a6cfe90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Tue, 23 Apr 2024 22:25:42 +0200 Subject: [PATCH 13/20] Bring over the deleted API POST method. --- .../Controllers/AdminController.cs | 116 ++++++++++++++---- Lombiq.JsonEditor/Startup.cs | 1 - 2 files changed, 89 insertions(+), 28 deletions(-) diff --git a/Lombiq.JsonEditor/Controllers/AdminController.cs b/Lombiq.JsonEditor/Controllers/AdminController.cs index 509ed55..e803305 100644 --- a/Lombiq.JsonEditor/Controllers/AdminController.cs +++ b/Lombiq.JsonEditor/Controllers/AdminController.cs @@ -1,6 +1,6 @@ -using AngleSharp.Common; using Lombiq.HelpfulLibraries.OrchardCore.Contents; using Lombiq.HelpfulLibraries.OrchardCore.DependencyInjection; +using Lombiq.HelpfulLibraries.OrchardCore.Validation; using Lombiq.JsonEditor.ViewModels; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -9,23 +9,31 @@ using Microsoft.Extensions.Localization; using OrchardCore.Admin; using OrchardCore.ContentManagement; +using OrchardCore.ContentManagement.Handlers; using OrchardCore.ContentManagement.Metadata; using OrchardCore.Contents; -using OrchardCore.Contents.Controllers; using OrchardCore.DisplayManagement; using OrchardCore.DisplayManagement.Layout; using OrchardCore.DisplayManagement.Notify; using OrchardCore.DisplayManagement.Title; using OrchardCore.Title.ViewModels; using System; +using System.Linq; +using System.Net; using System.Security.Claims; using System.Text.Json; +using System.Text.Json.Settings; using System.Threading.Tasks; namespace Lombiq.JsonEditor.Controllers; public class AdminController : Controller { + private static readonly JsonMergeSettings _updateJsonMergeSettings = new() + { + MergeArrayHandling = MergeArrayHandling.Replace, + }; + private readonly IAuthorizationService _authorizationService; private readonly IContentManager _contentManager; private readonly IContentDefinitionManager _contentDefinitionManager; @@ -33,7 +41,6 @@ public class AdminController : Controller private readonly INotifier _notifier; private readonly IPageTitleBuilder _pageTitleBuilder; private readonly IShapeFactory _shapeFactory; - private readonly Lazy _contentApiControllerLazy; private readonly IStringLocalizer T; private readonly IHtmlLocalizer H; @@ -43,8 +50,7 @@ public AdminController( INotifier notifier, IPageTitleBuilder pageTitleBuilder, IShapeFactory shapeFactory, - IOrchardServices services, - Lazy contentApiControllerLazy) + IOrchardServices services) { _authorizationService = services.AuthorizationService.Value; _contentManager = services.ContentManager.Value; @@ -53,7 +59,6 @@ public AdminController( _notifier = notifier; _pageTitleBuilder = pageTitleBuilder; _shapeFactory = shapeFactory; - _contentApiControllerLazy = contentApiControllerLazy; T = services.StringLocalizer.Value; H = services.HtmlLocalizer.Value; } @@ -132,34 +137,91 @@ public async Task EditPost( private Task CanEditAsync(ContentItem contentItem) => _authorizationService.AuthorizeAsync(User, CommonPermissions.EditContent, contentItem); - private async Task UpdateContentAsync(ContentItem contentItem, bool isDraft) + private Task UpdateContentAsync(ContentItem contentItem, bool isDraft) => + PostContentAsync(contentItem, isDraft); + + private static bool IsContinue(string submitString) => + submitString?.EndsWithOrdinalIgnoreCase("AndContinue") == true; + + private static string GetName(ContentItem contentItem) => + string.IsNullOrWhiteSpace(contentItem.DisplayText) + ? contentItem.ContentType + : $"\"{contentItem.DisplayText}\""; + + // Based on the OrchardCore.Contents.Controllers.ApiController.Post action that was deleted in + // https://github.com/OrchardCMS/OrchardCore/commit/d524386b2f792f35773324ae482247e80a944266 to replace with minimal + // APIs that can't be reused the same way. + private async Task PostContentAsync(ContentItem model, bool draft) { - // The Content API Controller requires the AccessContentApi permission. As this isn't an external API request it - // doesn't make sense to require this permission. So we create a temporary claims principal and explicitly grant - // the permission. - var currentUser = User; - HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(User.Claims.Concat(Permissions.AccessContentApi))); + // It is really important to keep the proper method calls order with the ContentManager + // so that all event handlers gets triggered in the right sequence. + + if (await _contentManager.GetAsync(model.ContentItemId, VersionOptions.DraftRequired) is { } contentItem) + { + if (!await _authorizationService.AuthorizeAsync(User, CommonPermissions.EditContent, contentItem)) + { + return this.ChallengeOrForbid("Api"); + } + + contentItem.Merge(model, _updateJsonMergeSettings); + + await _contentManager.UpdateAsync(contentItem); + var result = await _contentManager.ValidateAsync(contentItem); + if (CheckContentValidationResult(result) is { } problem) return problem; + } + else + { + if (string.IsNullOrEmpty(model.ContentType) || await _contentDefinitionManager.GetTypeDefinitionAsync(model.ContentType) == null) + { + return BadRequest(); + } + + contentItem = await _contentManager.NewAsync(model.ContentType); + contentItem.Owner = User.FindFirstValue(ClaimTypes.NameIdentifier); - try + if (!await _authorizationService.AuthorizeAsync(User, CommonPermissions.PublishContent, contentItem)) + { + return this.ChallengeOrForbid("Api"); + } + + contentItem.Merge(model); + + var result = await _contentManager.UpdateValidateAndCreateAsync(contentItem, VersionOptions.Draft); + if (CheckContentValidationResult(result) is { } problem) return problem; + } + + if (draft) { - // Here the API controller is called directly. The behavior is the same as if we sent a POST request using an - // HTTP client (except the permission bypass above), but it's faster and more resource-efficient. - var contentApiController = _contentApiControllerLazy.Value; - contentApiController.ControllerContext.HttpContext = HttpContext; - return await contentApiController.Post(contentItem, isDraft); + await _contentManager.SaveDraftAsync(contentItem); } - finally + else { - // Ensure that the original claims principal is restored, just in case. - HttpContext.User = currentUser; + await _contentManager.PublishAsync(contentItem); } + + return Ok(contentItem); } - private static bool IsContinue(string submitString) => - submitString?.EndsWithOrdinalIgnoreCase("AndContinue") == true; + private ActionResult CheckContentValidationResult(ContentValidateResult result) + { + if (!result.Succeeded) + { + // Add the validation results to the ModelState to present the errors as part of the response. + result.AddValidationErrorsToModelState(ModelState); + } - private static string GetName(ContentItem contentItem) => - string.IsNullOrWhiteSpace(contentItem.DisplayText) - ? contentItem.ContentType - : $"\"{contentItem.DisplayText}\""; + // We check the model state after calling all handlers because they trigger WF content events so, even they are not + // intended to add model errors (only drivers), a WF content task may be executed inline and add some model errors. + if (!ModelState.IsValid) + { + return ValidationProblem(new ValidationProblemDetails(ModelState) + { + Title = T["One or more validation errors occurred."], + Detail = string.Join(", ", ModelState.Values.SelectMany(x => x.Errors.Select(x => x.ErrorMessage))), + Status = (int)HttpStatusCode.BadRequest, + }); + } + + return null; + } } diff --git a/Lombiq.JsonEditor/Startup.cs b/Lombiq.JsonEditor/Startup.cs index 47c104f..df8df56 100644 --- a/Lombiq.JsonEditor/Startup.cs +++ b/Lombiq.JsonEditor/Startup.cs @@ -40,7 +40,6 @@ public override void ConfigureServices(IServiceCollection services) { services.AddScoped(); services.AddOrchardServices(); - services.AddScoped(); services.AddContentSecurityPolicyProvider(); } } From d611f8172d207ddc14e80da44e920f6a71218ea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Tue, 23 Apr 2024 22:44:45 +0200 Subject: [PATCH 14/20] unusing --- Lombiq.JsonEditor/Startup.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Lombiq.JsonEditor/Startup.cs b/Lombiq.JsonEditor/Startup.cs index df8df56..aa34e96 100644 --- a/Lombiq.JsonEditor/Startup.cs +++ b/Lombiq.JsonEditor/Startup.cs @@ -10,7 +10,6 @@ using OrchardCore.Admin; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Display.ContentDisplay; -using OrchardCore.Contents.Controllers; using OrchardCore.ContentTypes.Editors; using OrchardCore.Modules; using OrchardCore.ResourceManagement; From 8f1623f8f266aca64ffd2be4003d2ff3287f1040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Sat, 27 Apr 2024 19:31:48 +0200 Subject: [PATCH 15/20] Update OC package version. --- Lombiq.JsonEditor/Lombiq.JsonEditor.csproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj index 8783b92..9f214c8 100644 --- a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj +++ b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj @@ -36,12 +36,12 @@ - - - - - - + + + + + + From 6300c3a051d8c458d5f5fd9cc4442ef5c92c8011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Sat, 4 May 2024 12:57:04 +0200 Subject: [PATCH 16/20] Update OC versions --- Lombiq.JsonEditor/Lombiq.JsonEditor.csproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj index 9f214c8..71943e4 100644 --- a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj +++ b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj @@ -36,12 +36,12 @@ - - - - - - + + + + + + From dff4b438dde4317ecf8309206276befc7bda173b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Tue, 7 May 2024 21:08:58 +0200 Subject: [PATCH 17/20] Update OC to the latest preview. --- Lombiq.JsonEditor/Lombiq.JsonEditor.csproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj index 71943e4..e2b4b93 100644 --- a/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj +++ b/Lombiq.JsonEditor/Lombiq.JsonEditor.csproj @@ -36,12 +36,12 @@ - - - - - - + + + + + + From 00dd65e273514b267c816f20a2660a6fb6bfd976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Fri, 10 May 2024 11:34:56 +0200 Subject: [PATCH 18/20] Remove strange leftover `var`. --- Lombiq.JsonEditor/Views/JsonField.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lombiq.JsonEditor/Views/JsonField.cshtml b/Lombiq.JsonEditor/Views/JsonField.cshtml index dc632a2..3061c0d 100644 --- a/Lombiq.JsonEditor/Views/JsonField.cshtml +++ b/Lombiq.JsonEditor/Views/JsonField.cshtml @@ -10,6 +10,6 @@ dangerous content (such as JS code injection) in there, so it's safe to pass the value into Html.Raw(). *@ From 98a4d9d451df20fa088b4b99da6020a1fb602248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Sun, 12 May 2024 18:13:24 +0200 Subject: [PATCH 19/20] Update Lombiq.JsonEditor/Controllers/AdminController.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: József Horváth --- Lombiq.JsonEditor/Controllers/AdminController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lombiq.JsonEditor/Controllers/AdminController.cs b/Lombiq.JsonEditor/Controllers/AdminController.cs index e803305..da0089e 100644 --- a/Lombiq.JsonEditor/Controllers/AdminController.cs +++ b/Lombiq.JsonEditor/Controllers/AdminController.cs @@ -217,7 +217,7 @@ private ActionResult CheckContentValidationResult(ContentValidateResult result) return ValidationProblem(new ValidationProblemDetails(ModelState) { Title = T["One or more validation errors occurred."], - Detail = string.Join(", ", ModelState.Values.SelectMany(x => x.Errors.Select(x => x.ErrorMessage))), + Detail = string.Join(", ", ModelState.Values.SelectMany(state => state.Errors.Select(error => error.ErrorMessage))), Status = (int)HttpStatusCode.BadRequest, }); } From 4a93107ec986970ac801642fa738c8831911f2bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Sun, 12 May 2024 18:13:40 +0200 Subject: [PATCH 20/20] Update Lombiq.JsonEditor/Models/JsonEditorOptions.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: József Horváth --- Lombiq.JsonEditor/Models/JsonEditorOptions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Lombiq.JsonEditor/Models/JsonEditorOptions.cs b/Lombiq.JsonEditor/Models/JsonEditorOptions.cs index c17d8c3..09ae0b6 100644 --- a/Lombiq.JsonEditor/Models/JsonEditorOptions.cs +++ b/Lombiq.JsonEditor/Models/JsonEditorOptions.cs @@ -30,6 +30,7 @@ public class JsonEditorOptions public bool History { get; set; } = true; [JsonPropertyName("mode")] + [JsonInclude] private string ModeString { get; set; } = "tree"; ///