diff --git a/src/modules/Elsa.Common/Converters/DecimalJsonConverter.cs b/src/modules/Elsa.Common/Converters/DecimalJsonConverter.cs new file mode 100644 index 000000000..95b172545 --- /dev/null +++ b/src/modules/Elsa.Common/Converters/DecimalJsonConverter.cs @@ -0,0 +1,32 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Elsa.Common.Converters; + +/// +/// Converts decimals to and from JSON strings. +/// +public class DecimalJsonConverter : JsonConverter +{ + /// + public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Number) + return reader.GetDecimal(); + + if (reader.TokenType == JsonTokenType.String) + { + var value = reader.GetString()!; + return decimal.Parse(value); + } + + throw new JsonException("Expected number or string."); + } + + /// + public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options) + { + // Write the decimal as a JSON number + writer.WriteNumberValue(value); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Core/Serialization/Converters/IntegerConverter.cs b/src/modules/Elsa.Common/Converters/IntegerJsonConverter.cs similarity index 50% rename from src/modules/Elsa.Workflows.Core/Serialization/Converters/IntegerConverter.cs rename to src/modules/Elsa.Common/Converters/IntegerJsonConverter.cs index a39129003..8c2bbf5b7 100644 --- a/src/modules/Elsa.Workflows.Core/Serialization/Converters/IntegerConverter.cs +++ b/src/modules/Elsa.Common/Converters/IntegerJsonConverter.cs @@ -1,28 +1,32 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elsa.Workflows.Serialization.Converters; +namespace Elsa.Common.Converters; /// /// Converts integers to and from JSON strings. /// -public class IntegerConverter : JsonConverter +public class IntegerJsonConverter : JsonConverter { /// public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - // Read the JSON string value and parse it as an integer - var value = reader.GetString()!; - var integer = int.Parse(value); - - // Return the parsed integer - return integer; + if (reader.TokenType == JsonTokenType.Number) + return reader.GetInt32(); + + if (reader.TokenType == JsonTokenType.String) + { + var value = reader.GetString()!; + return int.Parse(value); + } + + throw new JsonException("Expected number or string."); } /// public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options) { - // Write the integer as a JSON number + // Write the integer as a JSON number. writer.WriteNumberValue(value); } } \ No newline at end of file diff --git a/src/modules/Elsa.Common/Serialization/ConfigurableSerializer.cs b/src/modules/Elsa.Common/Serialization/ConfigurableSerializer.cs index fc5c2179d..ab7185eb3 100644 --- a/src/modules/Elsa.Common/Serialization/ConfigurableSerializer.cs +++ b/src/modules/Elsa.Common/Serialization/ConfigurableSerializer.cs @@ -4,6 +4,7 @@ using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; using System.Text.Unicode; using Elsa.Common.Contracts; +using Elsa.Common.Converters; using Microsoft.Extensions.DependencyInjection; namespace Elsa.Common.Serialization; @@ -61,6 +62,8 @@ public abstract class ConfigurableSerializer options.Converters.Add(new JsonStringEnumConverter()); options.Converters.Add(JsonMetadataServices.TimeSpanConverter); + options.Converters.Add(new IntegerJsonConverter()); + options.Converters.Add(new DecimalJsonConverter()); return options; } diff --git a/src/modules/Elsa.Workflows.Core/Expressions/ObjectExpressionHandler.cs b/src/modules/Elsa.Workflows.Core/Expressions/ObjectExpressionHandler.cs index 83bbdbfc7..6f4877850 100644 --- a/src/modules/Elsa.Workflows.Core/Expressions/ObjectExpressionHandler.cs +++ b/src/modules/Elsa.Workflows.Core/Expressions/ObjectExpressionHandler.cs @@ -1,17 +1,21 @@ +using System.Diagnostics.CodeAnalysis; using System.Text.Json; +using Elsa.Common.Converters; using Elsa.Expressions.Contracts; using Elsa.Expressions.Helpers; using Elsa.Expressions.Models; -using Elsa.Workflows.Serialization.Converters; +using JetBrains.Annotations; namespace Elsa.Workflows.Expressions; /// /// Evaluates an object expression. /// +[UsedImplicitly] public class ObjectExpressionHandler : IExpressionHandler { /// + [RequiresUnreferencedCode("The type is not known at compile time.")] public ValueTask EvaluateAsync(Expression expression, Type returnType, ExpressionExecutionContext context, ExpressionEvaluatorOptions options) { var value = expression.Value.ConvertTo() ?? ""; @@ -20,7 +24,8 @@ public class ObjectExpressionHandler : IExpressionHandler return ValueTask.FromResult(default(object?)); var serializerOptions = new JsonSerializerOptions(); - serializerOptions.Converters.Add(new IntegerConverter()); + serializerOptions.Converters.Add(new IntegerJsonConverter()); + serializerOptions.Converters.Add(new DecimalJsonConverter()); var converterOptions = new ObjectConverterOptions(serializerOptions); var model = value.ConvertTo(returnType, converterOptions);