diff --git a/src/modules/Elsa.Workflows.Core/Serialization/Converters/FuncExpressionValueConverter.cs b/src/modules/Elsa.Workflows.Core/Serialization/Converters/FuncExpressionValueConverter.cs
new file mode 100644
index 000000000..ad13c2bf7
--- /dev/null
+++ b/src/modules/Elsa.Workflows.Core/Serialization/Converters/FuncExpressionValueConverter.cs
@@ -0,0 +1,28 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Elsa.Expressions.Models;
+
+namespace Elsa.Workflows.Serialization.Converters;
+
+///
+/// Prevents System.Text.Json from trying to serialize the compiled delegate.
+/// Always emits null and cannot rehydrate a Func.
+///
+public class FuncExpressionValueConverter : JsonConverter>>
+{
+ public override Func> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ // Skip whatever value is in the JSON (probably null).
+ if (reader.TokenType != JsonTokenType.Null)
+ reader.Skip();
+
+ // We can't deserialize a delegate, so return null.
+ return null!;
+ }
+
+ public override void Write(Utf8JsonWriter writer, Func> value, JsonSerializerOptions options)
+ {
+ // Emit a JSON null instead of trying to serialize the delegate
+ writer.WriteNullValue();
+ }
+}
diff --git a/src/modules/Elsa.Workflows.Core/Serialization/Converters/FuncExpressionValueConverterFactory.cs b/src/modules/Elsa.Workflows.Core/Serialization/Converters/FuncExpressionValueConverterFactory.cs
new file mode 100644
index 000000000..0b7cd10b0
--- /dev/null
+++ b/src/modules/Elsa.Workflows.Core/Serialization/Converters/FuncExpressionValueConverterFactory.cs
@@ -0,0 +1,12 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Elsa.Expressions.Models;
+
+namespace Elsa.Workflows.Serialization.Converters;
+
+public class FuncExpressionConverterFactory : JsonConverterFactory
+{
+ public override bool CanConvert(Type t) => t == typeof(Func>);
+
+ public override JsonConverter CreateConverter(Type t, JsonSerializerOptions opts) => new FuncExpressionValueConverter();
+}
diff --git a/src/modules/Elsa.Workflows.Core/Serialization/Serializers/ApiSerializer.cs b/src/modules/Elsa.Workflows.Core/Serialization/Serializers/ApiSerializer.cs
index a3423338a..7f97058db 100644
--- a/src/modules/Elsa.Workflows.Core/Serialization/Serializers/ApiSerializer.cs
+++ b/src/modules/Elsa.Workflows.Core/Serialization/Serializers/ApiSerializer.cs
@@ -10,9 +10,8 @@ public class ApiSerializer : ConfigurableSerializer, IApiSerializer
///
/// Initializes a new instance of the class.
///
- public ApiSerializer(IServiceProvider serviceProvider) : base(serviceProvider)
- {
- }
+ public ApiSerializer(IServiceProvider serviceProvider)
+ : base(serviceProvider) { }
///
public string Serialize(object model)
@@ -41,6 +40,7 @@ public class ApiSerializer : ConfigurableSerializer, IApiSerializer
protected override void AddConverters(JsonSerializerOptions options)
{
options.Converters.Add(CreateInstance());
+ options.Converters.Add(CreateInstance());
}
JsonSerializerOptions IApiSerializer.GetOptions() => GetOptions();
@@ -50,4 +50,4 @@ public class ApiSerializer : ConfigurableSerializer, IApiSerializer
ApplyOptions(options);
return options;
}
-}
\ No newline at end of file
+}
diff --git a/src/modules/Elsa.Workflows.Core/Serialization/Serializers/BookmarkPayloadSerializer.cs b/src/modules/Elsa.Workflows.Core/Serialization/Serializers/BookmarkPayloadSerializer.cs
index 0d6e73f15..9dab96949 100644
--- a/src/modules/Elsa.Workflows.Core/Serialization/Serializers/BookmarkPayloadSerializer.cs
+++ b/src/modules/Elsa.Workflows.Core/Serialization/Serializers/BookmarkPayloadSerializer.cs
@@ -18,18 +18,21 @@ public class BookmarkPayloadSerializer : IBookmarkPayloadSerializer
{
// Enables serialization of ValueTuples, which use fields instead of properties.
IncludeFields = true,
- PropertyNameCaseInsensitive = true
+ PropertyNameCaseInsensitive = true,
};
-
+
_settings.Converters.Add(new TypeJsonConverter(wellKnownTypeRegistry));
+ _settings.Converters.Add(new FuncExpressionValueConverter());
}
///
- public T Deserialize(string json) where T : notnull => JsonSerializer.Deserialize(json, _settings)!;
+ public T Deserialize(string json)
+ where T : notnull => JsonSerializer.Deserialize(json, _settings)!;
///
public object Deserialize(string json, Type type) => JsonSerializer.Deserialize(json, type, _settings)!;
///
- public string Serialize(T payload) where T : notnull => JsonSerializer.Serialize(payload, payload.GetType(), _settings);
-}
\ No newline at end of file
+ public string Serialize(T payload)
+ where T : notnull => JsonSerializer.Serialize(payload, payload.GetType(), _settings);
+}
diff --git a/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonActivitySerializer.cs b/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonActivitySerializer.cs
index 62f65db9a..7e3f996aa 100644
--- a/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonActivitySerializer.cs
+++ b/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonActivitySerializer.cs
@@ -37,5 +37,6 @@ public class JsonActivitySerializer(IServiceProvider serviceProvider) : Configur
options.Converters.Add(CreateInstance());
options.Converters.Add(CreateInstance());
options.Converters.Add(CreateInstance());
+ options.Converters.Add(CreateInstance());
}
-}
\ No newline at end of file
+}
diff --git a/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonPayloadSerializer.cs b/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonPayloadSerializer.cs
index c5ab81a8f..9c97db7a8 100644
--- a/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonPayloadSerializer.cs
+++ b/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonPayloadSerializer.cs
@@ -20,7 +20,7 @@ public class JsonPayloadSerializer : IPayloadSerializer
{
_serviceProvider = serviceProvider;
}
-
+
///
public string Serialize(object payload)
{
@@ -82,8 +82,10 @@ public class JsonPayloadSerializer : IPayloadSerializer
options.Converters.Add(GetService());
options.Converters.Add(GetService());
options.Converters.Add(GetService());
+ options.Converters.Add(new FuncExpressionValueConverter());
return options;
}
-
- private T GetService() where T : notnull => ActivatorUtilities.GetServiceOrCreateInstance(_serviceProvider);
-}
\ No newline at end of file
+
+ private T GetService()
+ where T : notnull => ActivatorUtilities.GetServiceOrCreateInstance(_serviceProvider);
+}
diff --git a/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonWorkflowStateSerializer.cs b/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonWorkflowStateSerializer.cs
index ad664f7e8..faf4215b8 100644
--- a/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonWorkflowStateSerializer.cs
+++ b/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonWorkflowStateSerializer.cs
@@ -20,7 +20,8 @@ public class JsonWorkflowStateSerializer : ConfigurableSerializer, IWorkflowStat
///
/// Initializes a new instance of the class.
///
- public JsonWorkflowStateSerializer(IServiceProvider serviceProvider, IWellKnownTypeRegistry wellKnownTypeRegistry, ILoggerFactory loggerFactory) : base(serviceProvider)
+ public JsonWorkflowStateSerializer(IServiceProvider serviceProvider, IWellKnownTypeRegistry wellKnownTypeRegistry, ILoggerFactory loggerFactory)
+ : base(serviceProvider)
{
_wellKnownTypeRegistry = wellKnownTypeRegistry;
_loggerFactory = loggerFactory;
@@ -128,10 +129,7 @@ public class JsonWorkflowStateSerializer : ConfigurableSerializer, IWorkflowStat
public override JsonSerializerOptions GetOptions()
{
var options = base.GetOptions();
- return new(options)
- {
- ReferenceHandler = new CrossScopedReferenceHandler()
- };
+ return new(options) { ReferenceHandler = new CrossScopedReferenceHandler() };
}
///
@@ -140,5 +138,6 @@ public class JsonWorkflowStateSerializer : ConfigurableSerializer, IWorkflowStat
options.Converters.Add(new TypeJsonConverter(_wellKnownTypeRegistry));
options.Converters.Add(new PolymorphicObjectConverterFactory(_wellKnownTypeRegistry));
options.Converters.Add(new VariableConverterFactory(_wellKnownTypeRegistry, _loggerFactory));
+ options.Converters.Add(new FuncExpressionValueConverter());
}
-}
\ No newline at end of file
+}
diff --git a/src/modules/Elsa.Workflows.Core/Serialization/Serializers/SafeSerializer.cs b/src/modules/Elsa.Workflows.Core/Serialization/Serializers/SafeSerializer.cs
index fbfd58a82..46b7b5400 100644
--- a/src/modules/Elsa.Workflows.Core/Serialization/Serializers/SafeSerializer.cs
+++ b/src/modules/Elsa.Workflows.Core/Serialization/Serializers/SafeSerializer.cs
@@ -13,9 +13,8 @@ namespace Elsa.Workflows.Serialization.Serializers;
public class SafeSerializer : ConfigurableSerializer, ISafeSerializer
{
///
- public SafeSerializer(IServiceProvider serviceProvider) : base(serviceProvider)
- {
- }
+ public SafeSerializer(IServiceProvider serviceProvider)
+ : base(serviceProvider) { }
///
[RequiresUnreferencedCode("The type T may be trimmed.")]
@@ -78,5 +77,6 @@ public class SafeSerializer : ConfigurableSerializer, ISafeSerializer
options.Converters.Add(new TypeJsonConverter(WellKnownTypeRegistry.CreateDefault()));
options.Converters.Add(new SafeValueConverterFactory());
options.Converters.Add(new ExpressionJsonConverterFactory(expressionDescriptorRegistry));
+ options.Converters.Add(new FuncExpressionValueConverter());
}
-}
\ No newline at end of file
+}