How pass an object to functions and keep the modifications in a Durable Function?

CandidKilsborne 20 Reputation points
2024-07-20T15:36:08.38+00:00

I've been working on learning more about Azure Functions and I'm currently working on a project using Durable Functions. I'm not sure if I'm not understanding correctly or if I'm just doing something incorrectly, but my understanding with Durable Functions is that I can call a function and save the return value to a variable and then pass that variable into the next function call. I'm attempting that but when I look at the logs when the next function gets executed, the object that was passed in has null values for all the fields.

Here's a screenshot of the code. The value of 'mergedPayload' is correct when coming out of the first function, but when it's passed into the next one it shows nulls when logged out. Ideally, I'll need to keep modifying this object a few times with different function calls.User's image

It's a .NET 8 Isolated project if that's useful.

Azure Functions
Azure Functions
An Azure service that provides an event-driven serverless compute platform.
4,681 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,656 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Sina Salam 7,441 Reputation points
    2024-07-21T13:43:48.0466667+00:00

    Hello CandidKilsborne,

    Welcome to the Microsoft Q&A and thank you for posting your questions here.

    Problem

    I understand that you are developing an Azure Durable Functions project in .NET 8 Isolated mode and you're facing an issue where an object (mergedPayload) loses its values (all fields become null) when passed between function calls within the orchestrator. You would also like to know how to correctly pass and retain the modifications of the object between the function calls in a Durable Function.

    Solution

    The behavior you've described in your explanation can occur due to serialization and deserialization issues in Durable Functions. Regarding your question, this is how to pass an object between functions and keep the modifications within a Durable Function in a .NET 8 Isolated project.

    1. Ensure your data class is serializable by using appropriate attributes for JSON serialization.
          using System.Text.Json.Serialization; 
            public class Payload
            {
                [JsonPropertyName("property1")]
                public string Property1 { get; set; }
                [JsonPropertyName("property2")]
                public int Property2 { get; set; }
                // Add other properties as needed
            }
      
    2. Define the orchestrator function that calls activity functions and passes the modified object between them.
             public static class DurableFunctionOrchestrator
            {
                [Function("OrchestratorFunction")]
                public static async Task RunOrchestrator(
                    [OrchestrationTrigger] IDurableOrchestrationContext context)
                {
                    var initialPayload = new Payload { Property1 = "InitialValue", Property2 = 100 };
                    var mergedPayload = await context.CallActivityAsync<Payload>("MergeFunction", initialPayload);
                    var resultPayload = await context.CallActivityAsync<Payload>("ProcessFunction", mergedPayload);
                    // Log or use the final result as needed
                    context.SetOutput(resultPayload);
                }
            }
      
    3. Ensure you log the payload before and after each modification to trace the state of your object.
         using Microsoft.Extensions.Logging;
         using System.Text.Json;
            public static class ActivityFunctions
            {
                [Function("MergeFunction")]
                public static async Task<Payload> MergeFunction([ActivityTrigger] Payload payload, ILogger log)
                {
                    log.LogInformation($"MergeFunction received payload: {JsonSerializer.Serialize(payload)}");
                    
                    // Modify the payload
                    payload.Property1 = "MergedValue";
                    
                    log.LogInformation($"MergeFunction modified payload: {JsonSerializer.Serialize(payload)}");
                    return payload;
                }
                [Function("ProcessFunction")]
                public static async Task<Payload> ProcessFunction([ActivityTrigger] Payload payload, ILogger log)
                {
                    log.LogInformation($"ProcessFunction received payload: {JsonSerializer.Serialize(payload)}");
                    
                    // Further modify the payload
                    payload.Property2 += 200;
                    
                    log.LogInformation($"ProcessFunction modified payload: {JsonSerializer.Serialize(payload)}");
                    return payload;
                }
            }
      

    By following the simple three steps above, the object retains its modifications as it is passed between the functions in your Durable Function orchestration.

    Accept Answer

    I hope this is helpful! Do not hesitate to let me know if you have any other questions.

    ** Please don't forget to close up the thread here by upvoting and accept it as an answer if it is helpful ** so that others in the community facing similar issues can easily find the solution.

    Best Regards,

    Sina Salam

    0 comments No comments