From 95a27b82a2e58acee93e9614879b646b51f02059 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 25 Feb 2020 10:40:39 +0100 Subject: [PATCH] Fix for jobject casting issue --- .../Controllers/InstallApiController.cs | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web/Install/Controllers/InstallApiController.cs b/src/Umbraco.Web/Install/Controllers/InstallApiController.cs index 3b8e9b48d3..0b94058137 100644 --- a/src/Umbraco.Web/Install/Controllers/InstallApiController.cs +++ b/src/Umbraco.Web/Install/Controllers/InstallApiController.cs @@ -91,7 +91,7 @@ namespace Umbraco.Web.Install.Controllers var step = _installSteps.GetAllSteps().Single(x => x.Name == item.Name); // if this step has any instructions then extract them - installModel.Instructions.TryGetValue(item.Name, out var instruction); // else null + var instruction = GetInstruction(installModel, item, step); // if this step doesn't require execution then continue to the next one, this is just a fail-safe check. if (StepRequiresExecution(step, instruction) == false) @@ -153,6 +153,18 @@ namespace Umbraco.Web.Install.Controllers return new InstallProgressResultModel(true, "", ""); } + private static object GetInstruction(InstallInstructions installModel, InstallTrackingItem item, InstallSetupStep step) + { + installModel.Instructions.TryGetValue(item.Name, out var instruction); // else null + + if (instruction is JObject jObject) + { + instruction = jObject?.ToObject(step.StepType); + } + + return instruction; + } + /// /// We'll peek ahead and check if it's RequiresExecution is returning true. If it /// is not, we'll dequeue that step and peek ahead again (recurse) @@ -177,8 +189,7 @@ namespace Umbraco.Web.Install.Controllers var step = _installSteps.GetAllSteps().Single(x => x.Name == item.Name); // if this step has any instructions then extract them - object instruction; - installModel.Instructions.TryGetValue(item.Name, out instruction); // else null + var instruction = GetInstruction(installModel, item, step); // if the step requires execution then return its name if (StepRequiresExecution(step, instruction)) @@ -230,7 +241,12 @@ namespace Umbraco.Web.Install.Controllers { using (_proflog.TraceDuration($"Executing installation step: '{step.Name}'.", "Step completed")) { - var model = Convert.ChangeType(instruction, step.StepType); + var modelAttempt = instruction.TryConvertTo(step.StepType); + if (!modelAttempt.Success) + { + throw new InvalidCastException($"Cannot cast/convert {step.GetType().FullName} into {step.StepType.FullName}"); + } + var model = modelAttempt.Result; var genericStepType = typeof(InstallSetupStep<>); Type[] typeArgs = { step.StepType }; var typedStepType = genericStepType.MakeGenericType(typeArgs);