Skip to content

Commit

Permalink
Fix recipe steps with polymorphic types (OrchardCMS#15320)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastienros authored and urbanit committed Mar 18, 2024
1 parent 4fe3f96 commit 045c7bb
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using OrchardCore.AdminMenu.Services;
using OrchardCore.Deployment;
using OrchardCore.Json;

namespace OrchardCore.AdminMenu.Deployment
{
public class AdminMenuDeploymentSource : IDeploymentSource
{
private readonly IAdminMenuService _adminMenuService;
private readonly JsonSerializerOptions _serializationOptions;

public AdminMenuDeploymentSource(IAdminMenuService adminMenuService)
public AdminMenuDeploymentSource(IAdminMenuService adminMenuService, IOptions<JsonDerivedTypesOptions> derivedTypesOptions)
{
_adminMenuService = adminMenuService;

// The recipe step contains polymorphic types which need to be resolved
_serializationOptions = new()
{
TypeInfoResolver = new PolymorphicJsonTypeInfoResolver(derivedTypesOptions.Value)
};
}

public async Task ProcessDeploymentStepAsync(DeploymentStep step, DeploymentPlanResult result)
Expand All @@ -32,7 +43,7 @@ public async Task ProcessDeploymentStepAsync(DeploymentStep step, DeploymentPlan

foreach (var adminMenu in (await _adminMenuService.GetAdminMenuListAsync()).AdminMenu)
{
var objectData = JObject.FromObject(adminMenu);
var objectData = JObject.FromObject(adminMenu, _serializationOptions);
data.Add(objectData);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
using System;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using OrchardCore.AdminMenu.Services;
using OrchardCore.Json;
using OrchardCore.Recipes.Models;
using OrchardCore.Recipes.Services;

Expand All @@ -14,10 +18,17 @@ namespace OrchardCore.AdminMenu.Recipes
public class AdminMenuStep : IRecipeStepHandler
{
private readonly IAdminMenuService _adminMenuService;
private readonly JsonSerializerOptions _serializationOptions;

public AdminMenuStep(IAdminMenuService adminMenuService)
public AdminMenuStep(IAdminMenuService adminMenuService, IOptions<JsonDerivedTypesOptions> derivedTypesOptions)
{
_adminMenuService = adminMenuService;

// The recipe step contains polymorphic types (menu items) which need to be resolved
_serializationOptions = new()
{
TypeInfoResolver = new PolymorphicJsonTypeInfoResolver(derivedTypesOptions.Value)
};
}

public async Task ExecuteAsync(RecipeExecutionContext context)
Expand All @@ -29,11 +40,9 @@ public async Task ExecuteAsync(RecipeExecutionContext context)

var model = context.Step.ToObject<AdminMenuStepModel>();

// var serializer = new JsonSerializer() { TypeNameHandling = TypeNameHandling.Auto };

foreach (var token in model.Data.Cast<JsonObject>())
{
var adminMenu = token.ToObject<Models.AdminMenu>(/*serializer*/);
var adminMenu = token.ToObject<Models.AdminMenu>(_serializationOptions);

// When the id is not supplied generate an id, otherwise replace the menu if it exists, or create a new menu.
if (string.IsNullOrEmpty(adminMenu.Id))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@ public AdminMenuNavigationProvidersCoordinator(
_logger = logger;
}

// We only add them if the caller uses the string "adminMenu").
// todo: use a public constant for the string
public async Task BuildNavigationAsync(string name, NavigationBuilder builder)
{
if (!string.Equals(NavigationConstants.AdminMenuId, name))
// We only add them if the caller uses the string "adminMenu".
if (name != NavigationConstants.AdminMenuId)
{
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using OrchardCore.Deployment;
using OrchardCore.Json;
using OrchardCore.Layers.Models;
using OrchardCore.Layers.Services;
using OrchardCore.Settings;
Expand All @@ -11,11 +15,21 @@ public class AllLayersDeploymentSource : IDeploymentSource
{
private readonly ILayerService _layerService;
private readonly ISiteService _siteService;
private readonly JsonSerializerOptions _serializationOptions;

public AllLayersDeploymentSource(ILayerService layerService, ISiteService siteService)
public AllLayersDeploymentSource(
ILayerService layerService,
ISiteService siteService,
IOptions<JsonDerivedTypesOptions> derivedTypesOptions)
{
_layerService = layerService;
_siteService = siteService;

// The recipe step contains polymorphic types which need to be resolved
_serializationOptions = new()
{
TypeInfoResolver = new PolymorphicJsonTypeInfoResolver(derivedTypesOptions.Value)
};
}

public async Task ProcessDeploymentStepAsync(DeploymentStep step, DeploymentPlanResult result)
Expand All @@ -32,7 +46,7 @@ public async Task ProcessDeploymentStepAsync(DeploymentStep step, DeploymentPlan
result.Steps.Add(new JsonObject
{
["name"] = "Layers",
["Layers"] = JArray.FromObject(layers.Layers),
["Layers"] = JArray.FromObject(layers.Layers, _serializationOptions),
});

var siteSettings = await _siteService.GetSiteSettingsAsync();
Expand Down
23 changes: 15 additions & 8 deletions src/OrchardCore.Modules/OrchardCore.Layers/Recipes/LayerStep.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using OrchardCore.Json;
using OrchardCore.Layers.Models;
using OrchardCore.Layers.Services;
using OrchardCore.Recipes.Models;
Expand All @@ -17,26 +21,28 @@ namespace OrchardCore.Layers.Recipes
/// </summary>
public class LayerStep : IRecipeStepHandler
{
// private readonly static JsonSerializer _jsonSerializer = new()
// {
// TypeNameHandling = TypeNameHandling.Auto,
// };

private readonly ILayerService _layerService;
private readonly IRuleMigrator _ruleMigrator;
private readonly IConditionIdGenerator _conditionIdGenerator;
private readonly IEnumerable<IConditionFactory> _factories;
private readonly JsonSerializerOptions _serializationOptions;

public LayerStep(
ILayerService layerService,
IRuleMigrator ruleMigrator,
IConditionIdGenerator conditionIdGenerator,
IEnumerable<IConditionFactory> factories)
IEnumerable<IConditionFactory> factories,
IOptions<JsonDerivedTypesOptions> derivedTypesOptions)
{
_layerService = layerService;
_ruleMigrator = ruleMigrator;
_conditionIdGenerator = conditionIdGenerator;
_factories = factories;

_serializationOptions = new()
{
TypeInfoResolver = new PolymorphicJsonTypeInfoResolver(derivedTypesOptions.Value)
};
}

public async Task ExecuteAsync(RecipeExecutionContext context)
Expand All @@ -46,7 +52,8 @@ public async Task ExecuteAsync(RecipeExecutionContext context)
return;
}

var model = context.Step.ToObject<LayersStepModel>();
// The recipe step contains polymorphic types which need to be resolved
var model = context.Step.ToObject<LayersStepModel>(_serializationOptions);

var allLayers = await _layerService.LoadLayersAsync();

Expand Down Expand Up @@ -94,7 +101,7 @@ public async Task ExecuteAsync(RecipeExecutionContext context)
var name = jCondition["Name"].ToString();
if (factories.TryGetValue(name, out var factory))
{
var factoryCondition = (Condition)jCondition.ToObject(factory.Create().GetType()/*, _jsonSerializer*/);
var factoryCondition = (Condition)jCondition.ToObject(factory.Create().GetType(), _serializationOptions);

layer.LayerRule.Conditions.Add(factoryCondition);
}
Expand Down

0 comments on commit 045c7bb

Please sign in to comment.