Add DecimalJsonConverter and update usage

Introduce a new DecimalJsonConverter class and refactor serialization setup. Renamed IntegerConverter to IntegerJsonConverter and updated its implementation to handle both number and string JSON tokens. Adjusted serializer options in ConfigurableSerializer and ObjectExpressionHandler accordingly.
This commit is contained in:
Sipke Schoorstra 2024-03-14 09:59:22 +01:00
parent 0b0e26a327
commit a0cda3830c
4 changed files with 55 additions and 11 deletions

View file

@ -0,0 +1,32 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Elsa.Common.Converters;
/// <summary>
/// Converts decimals to and from JSON strings.
/// </summary>
public class DecimalJsonConverter : JsonConverter<decimal>
{
/// <inheritdoc />
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.");
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options)
{
// Write the decimal as a JSON number
writer.WriteNumberValue(value);
}
}

View file

@ -1,28 +1,32 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Elsa.Workflows.Serialization.Converters;
namespace Elsa.Common.Converters;
/// <summary>
/// Converts integers to and from JSON strings.
/// </summary>
public class IntegerConverter : JsonConverter<int>
public class IntegerJsonConverter : JsonConverter<int>
{
/// <inheritdoc />
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.");
}
/// <inheritdoc />
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);
}
}

View file

@ -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;
}

View file

@ -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;
/// <summary>
/// Evaluates an object expression.
/// </summary>
[UsedImplicitly]
public class ObjectExpressionHandler : IExpressionHandler
{
/// <inheritdoc />
[RequiresUnreferencedCode("The type is not known at compile time.")]
public ValueTask<object?> EvaluateAsync(Expression expression, Type returnType, ExpressionExecutionContext context, ExpressionEvaluatorOptions options)
{
var value = expression.Value.ConvertTo<string>() ?? "";
@ -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);