diff --git a/src/modules/Elsa.Http/Activities/SendHttpRequest.cs b/src/modules/Elsa.Http/Activities/SendHttpRequest.cs
index ca13cb6a0..bfae9838d 100644
--- a/src/modules/Elsa.Http/Activities/SendHttpRequest.cs
+++ b/src/modules/Elsa.Http/Activities/SendHttpRequest.cs
@@ -112,7 +112,7 @@ public class HttpStatusCodeCase
///
/// Base class for activities that send HTTP requests.
///
-public abstract class SendHttpRequestBase : Activity
+public abstract class SendHttpRequestBase : Activity
{
///
/// The URL to send the request to.
diff --git a/src/modules/Elsa.Http/Features/HttpFeature.cs b/src/modules/Elsa.Http/Features/HttpFeature.cs
index d3c5f7109..28217c205 100644
--- a/src/modules/Elsa.Http/Features/HttpFeature.cs
+++ b/src/modules/Elsa.Http/Features/HttpFeature.cs
@@ -69,6 +69,7 @@ public class HttpFeature : FeatureBase
typeof(RouteData),
typeof(HttpRequest),
typeof(HttpResponse),
+ typeof(HttpResponseMessage),
typeof(HttpRequestHeaders)
}, "HTTP");
diff --git a/src/modules/Elsa.Workflows.Runtime/Services/AmbientActivityContext.cs b/src/modules/Elsa.Workflows.Runtime/Services/AmbientActivityContext.cs
deleted file mode 100644
index f0b3a2c3d..000000000
--- a/src/modules/Elsa.Workflows.Runtime/Services/AmbientActivityContext.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Elsa.Workflows.Runtime.Services;
-
-///
-/// Provides ambient context for activities.
-///
-internal static class AmbientActivityContext
-{
- private static readonly AsyncLocal IsDetachedState = new();
-
- ///
- /// Gets or sets a value indicating whether the current activity is detached.
- ///
- public static bool IsDetached
- {
- get => IsDetachedState.Value;
- set => IsDetachedState.Value = value;
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Runtime/Services/DefaultBackgroundActivityInvoker.cs b/src/modules/Elsa.Workflows.Runtime/Services/DefaultBackgroundActivityInvoker.cs
index 5ae61fd98..12f34a11a 100644
--- a/src/modules/Elsa.Workflows.Runtime/Services/DefaultBackgroundActivityInvoker.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Services/DefaultBackgroundActivityInvoker.cs
@@ -1,6 +1,7 @@
using Elsa.Common.Models;
using Elsa.Workflows.Core.Contracts;
using Elsa.Workflows.Core.Models;
+using Elsa.Workflows.Core.Services;
using Elsa.Workflows.Runtime.Contracts;
using Elsa.Workflows.Runtime.Middleware.Activities;
using Elsa.Workflows.Runtime.Models;
@@ -73,19 +74,38 @@ public class DefaultBackgroundActivityInvoker : IBackgroundActivityInvoker
// Invoke the activity.
await _activityInvoker.InvokeAsync(activityExecutionContext);
- // Capture any activity output produced by the activity.
+ // Capture any activity output produced by the activity (but only if the associated memory block is stored in the workflow itself).
var outputDescriptors = activityExecutionContext.ActivityDescriptor.Outputs;
var outputValues = new Dictionary();
foreach (var outputDescriptor in outputDescriptors)
{
var output = (Output?)outputDescriptor.ValueGetter(activityExecutionContext.Activity);
- var outputValue = output != null ? activityExecutionContext.Get(output.MemoryBlockReference()) : default!;
+
+ if(output == null)
+ continue;
+
+ var memoryBlockReference = output.MemoryBlockReference();
+
+ if(!activityExecutionContext.ExpressionExecutionContext.TryGetBlock(memoryBlockReference, out var memoryBlock))
+ continue;
+
+ var variableMetadata = memoryBlock.Metadata as VariableBlockMetadata;
+ var driver = variableMetadata?.StorageDriverType;
+
+ // We only capture output written to the workflow itself. Other drivers like blob storage, etc. will be ignored since the foreground context will be loading those.
+ if(driver != typeof(WorkflowStorageDriver))
+ continue;
+
+ var outputValue = activityExecutionContext.Get(memoryBlockReference);
if (outputValue != null)
outputValues[outputDescriptor.Name] = outputValue;
}
+ // Persist any variables that were written to by the activity.
+ await _variablePersistenceManager.SaveVariablesAsync(workflowExecutionContext);
+
// Resume the workflow, passing along the activity output.
// TODO: This approach will fail if the output is non-serializable. We need to find a way to pass the output to the workflow without serializing it.
var bookmarkId = scheduledBackgroundActivity.BookmarkId;