diff --git a/src/modules/Elsa.MongoDb/Features/MongoDbFeature.cs b/src/modules/Elsa.MongoDb/Features/MongoDbFeature.cs
index b0aabc67d..e168e37cf 100644
--- a/src/modules/Elsa.MongoDb/Features/MongoDbFeature.cs
+++ b/src/modules/Elsa.MongoDb/Features/MongoDbFeature.cs
@@ -1,4 +1,5 @@
using System.Text.Json;
+using System.Text.Json.Nodes;
using Elsa.Features.Abstractions;
using Elsa.Features.Services;
using Elsa.KeyValues.Entities;
@@ -8,6 +9,7 @@ using Elsa.MongoDb.Options;
using Elsa.MongoDb.Serializers;
using Elsa.Workflows.Memory;
using Elsa.Workflows.Runtime.Entities;
+using Elsa.Workflows.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
@@ -67,6 +69,7 @@ public class MongoDbFeature : FeatureBase
TryRegisterSerializerOrSkipWhenExist(typeof(Variable), new VariableSerializer());
TryRegisterSerializerOrSkipWhenExist(typeof(Version), new VersionSerializer());
TryRegisterSerializerOrSkipWhenExist(typeof(JsonElement), new JsonElementSerializer());
+ TryRegisterSerializerOrSkipWhenExist(typeof(JsonNode), new JsonNodeBsonConverter());
}
private static void RegisterClassMaps()
diff --git a/src/modules/Elsa.MongoDb/Serializers/JsonNodeBsonSerializer.cs b/src/modules/Elsa.MongoDb/Serializers/JsonNodeBsonSerializer.cs
new file mode 100644
index 000000000..51d793298
--- /dev/null
+++ b/src/modules/Elsa.MongoDb/Serializers/JsonNodeBsonSerializer.cs
@@ -0,0 +1,135 @@
+using System.Text.Json.Nodes;
+using MongoDB.Bson;
+using MongoDB.Bson.IO;
+using MongoDB.Bson.Serialization;
+
+namespace Elsa.MongoDb.Serializers;
+
+///
+/// Serializes a .
+///
+public class JsonNodeBsonConverter : IBsonSerializer
+{
+ ///
+ public Type ValueType => typeof(JsonNode);
+
+ ///
+ public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, JsonNode value)
+ {
+ if (value == null!)
+ {
+ context.Writer.WriteNull();
+ return;
+ }
+
+ context.Writer.WriteStartDocument();
+ context.Writer.WriteName("type");
+
+ switch (value)
+ {
+ case JsonObject jsonObject:
+ context.Writer.WriteString("JsonObject");
+ context.Writer.WriteName("value");
+ context.Writer.WriteString(jsonObject.ToJsonString());
+ break;
+
+ case JsonArray jsonArray:
+ context.Writer.WriteString("JsonArray");
+ context.Writer.WriteName("value");
+ context.Writer.WriteString(jsonArray.ToJsonString());
+ break;
+
+ case JsonValue jsonValue:
+ context.Writer.WriteString("JsonValue");
+ context.Writer.WriteName("value");
+ if (jsonValue.TryGetValue(out string? stringValue))
+ context.Writer.WriteString(stringValue);
+ else if (jsonValue.TryGetValue(out int intValue))
+ context.Writer.WriteInt32(intValue);
+ else if (jsonValue.TryGetValue(out int longValue))
+ context.Writer.WriteInt64(longValue);
+ else if (jsonValue.TryGetValue(out double doubleValue))
+ context.Writer.WriteDouble(doubleValue);
+ else if (jsonValue.TryGetValue(out bool boolValue))
+ context.Writer.WriteBoolean(boolValue);
+ else if (jsonValue.TryGetValue(out DateTimeOffset dateTimeOffsetValue))
+ context.Writer.WriteDateTime(dateTimeOffsetValue.ToUnixTimeMilliseconds());
+ else if (jsonValue.TryGetValue(out DateTime dateTimeValue))
+ context.Writer.WriteDateTime(new DateTimeOffset(dateTimeValue).ToUnixTimeMilliseconds());
+ else
+ throw new BsonSerializationException("Unsupported JsonValue type");
+ break;
+
+ default:
+ throw new BsonSerializationException($"Unexpected JsonNode type: {value.GetType()}");
+ }
+
+ context.Writer.WriteEndDocument();
+ }
+
+ public JsonNode Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
+ {
+ context.Reader.ReadStartDocument();
+ var type = context.Reader.ReadString();
+ context.Reader.ReadName(Utf8NameDecoder.Instance);
+
+ JsonNode result;
+ switch (type)
+ {
+ case "JsonObject":
+ var jsonObjectString = context.Reader.ReadString();
+ result = JsonNode.Parse(jsonObjectString);
+ break;
+
+ case "JsonArray":
+ var jsonArrayString = context.Reader.ReadString();
+ result = JsonNode.Parse(jsonArrayString);
+ break;
+
+ case "JsonValue":
+ var bsonType = context.Reader.GetCurrentBsonType();
+ switch (bsonType)
+ {
+ case BsonType.String:
+ result = JsonValue.Create(context.Reader.ReadString());
+ break;
+ case BsonType.Int32:
+ result = JsonValue.Create(context.Reader.ReadInt32());
+ break;
+ case BsonType.Int64:
+ result = JsonValue.Create(context.Reader.ReadInt64());
+ break;
+ case BsonType.Double:
+ result = JsonValue.Create(context.Reader.ReadDouble());
+ break;
+ case BsonType.Boolean:
+ result = JsonValue.Create(context.Reader.ReadBoolean());
+ break;
+ case BsonType.DateTime:
+ result = JsonValue.Create(context.Reader.ReadDateTime());
+ break;
+ default:
+ throw new BsonSerializationException($"Unsupported BSON type: {bsonType}");
+ }
+ break;
+
+ default:
+ throw new BsonSerializationException($"Unsupported JsonNode type: {type}");
+ }
+
+ context.Reader.ReadEndDocument();
+ return result!;
+ }
+
+ ///
+ public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
+ {
+ Serialize(context, args, (JsonNode)value);
+ }
+
+ object IBsonSerializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
+ {
+ return Deserialize(context, args);
+ }
+}
+