Issues with a struct type when calling TaskOrchestrationContext getInput - Guids are empty

adriana_malea 141 Reputation points
2024-07-03T10:14:06.26+00:00

Hello,

Trying to migrate a code from .NET6 to .NET8, isolated worker model, I have noticed that: if the orchestrator has a struct type parameter having a Guid field, getting the input from the orchestrator, with context.GetInput<T>(), results in an empty Guid.

<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.22.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.1.4" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.15.0" />

In Program.cs, I have this line: services.Configure<JsonSerializerOptions>(o => o.IncludeFields = true);

public class Message
{
	public InputModel Id { get; set; }
}

public struct InputModel
{
    public Guid Id { get; }
    public InputModel(Guid value) => Id = value;
    public static InputModel FromString(string value) => new InputModel(Guid.Parse(value));
}
     
//this is how the orchestrator is called     
     await client.ScheduleNewOrchestrationInstanceAsync(
         nameof(MyOrchestrator),
         new Message
           {
              Id = InputModel.FromString(data)
           },
         new StartOrchestrationOptions { InstanceId = rowKey });
            
//in the orchestrator, trying to get the Message        
    var message = ctx.GetInput<Message>();
//the message contains an empty Guid
Azure Functions
Azure Functions
An Azure service that provides an event-driven serverless compute platform.
4,978 questions
.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,841 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. adriana_malea 141 Reputation points
    2024-07-09T08:04:06.3633333+00:00

    I have found the issue: the InputModel struct should be serialized correctly.

    public class Message
    {
    public InputModel Id { get; set; }
    }
    [JsonConverter(typeof(InputModelConverter))]
    public struct InputModel
    {
    public Guid Id { get; }
    public InputModel(Guid value) => Id = value;
    public static InputModel FromString(string value) => new InputModel(Guid.Parse(value));
    }
    public class InputModelConverter : JsonConverter<InputModel>
    {
        public override InputModel Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            // Assuming the JSON value is a simple string that can be parsed as a Guid
            if (reader.TokenType != JsonTokenType.String)
            {
                throw new JsonException("Expected a string value.");
            }
            string guidString = reader.GetString();
            if (!Guid.TryParse(guidString, out Guid guidValue))
            {
                throw new JsonException("The string value is not a valid GUID.");
            }
            return InputModel.FromString(guidValue.ToString());
        }
        public override void Write(Utf8JsonWriter writer, InputModel value, JsonSerializerOptions options)
        {
            // Serialize the InputModel instance's Id as a string
            writer.WriteStringValue(value.Id.ToString());
        }
    }
    } 
    //this is how the orchestrator is called     
     await client.ScheduleNewOrchestrationInstanceAsync(
         nameof(MyOrchestrator),
         new Message
           {
              Id = InputModel.FromString(data)
           },
         new StartOrchestrationOptions { InstanceId = rowKey });
    //in the orchestrator, trying to get the Message        
    var message = ctx.GetInput<Message>();
    //the message contains the correct Guid now
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.