Open fcu423 opened 7 months ago
Guess it's related to this closed issue : https://github.com/Azure/azure-functions-durable-extension/issues/2577 In my case I try to pass a class as input, the class is initialized but the values are not retrieved.
@jviau are you aware of issues related to polymorphic (de)serialization with STJ?
I think I have ran into this before!
In dotnet isolated, durable extension uses the worker-wide configured converter from WorkerOptions - which is an Azure.Core.ObjectSerializer
. I think their JSON implementation uses a set of APIs from STJ that for some reason don't run polymorphic serialization.
@fcu423 you can see if this repros for you locally: try serializing/deserializing via System.Text.Json.JsonSerializer
and then via Azure.Core.Serialization.JsonObjectSerializer
. If I remember correctly, the first will respect the polymorphic attributes, the second will not.
We will need to consider how to let a customer specify a separate convert for just durable. It might be possible today via adding your own PostConfigure
call:
https://github.com/Azure/azure-functions-durable-extension/blob/dev/src/Worker.Extensions.DurableTask/DurableTaskExtensionStartup.cs#L34
Hello @jviau,
I have the same issue while using:
Calling ScheduleNewOrchestrationInstanceAsync with input param of type Message, both fields are assigned the correct values:
await client.ScheduleNewOrchestrationInstanceAsync(
nameof(MyOrchestrator),
new Message
{
Id = calloutData.Result.Id,
EntityId = AppEntityId.FromString(calloutData.Result.EntityId.ToString()),
},
new StartOrchestrationOptions { InstanceId = rowKey });
public class Message
{
public Guid Id { get; set; }
public AppEntityId EntityId { get; set; }
}
But, when trying to retrieve ctx.GetInput
Could you please suggest me how can I handle this? Thanks.
@amalea what is AppEntityId
? Can you verify serializing and deserializing this in a unit test via Azure.Core.Serialization.JsonObjectSerializer
?
Hello @jviau,
AppEntityId is a struct, like this:
public struct AppEntityId : IEquatable<AppEntityId >, IComparable<AppEntityId >, IComparable
{
public Guid Value { get; }
public AppEntityId (Guid value) => Value = value;
public static AppEntityId FromString(string value) => new AppEntityId (Guid.Parse(value));
}
I am not sure where exactly should I use serialization/deserialization in the above code.
@amalea, this doesn't look like it is related to this issue as you are not using polymorphic serialization. Yours looks like a general serialization issue external to durable. I recommend you write unit tests to validate you can serialize/deserialize your payload with System.Text.Json outside of durable.
Hello @jviau,
I have tried to isolate the problem and it seems that using struct type does not work with durable functions isolated worker / or some other lib has a wrong impact.
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));
}
await client.ScheduleNewOrchestrationInstanceAsync(
nameof(MyOrchestrator),
new Message
{
Id = InputModel.FromString(data)
},
new StartOrchestrationOptions { InstanceId = rowKey });
//after this call, Id is an empty Guid, even if the value is passed correctly, but that TaskOrchestrationContext GetInput modifies something and I can't find what/where
var message = ctx.GetInput<Message>();
In Program.cs, I have this line also:
services.Configure<JsonSerializerOptions>(o => o.IncludeFields = true);
Description
Using .NET 8 and azure functions in isolated mode, I have an
EventGridTrigger
function that starts up an orchestrator while providing a typed input as parameter. The parameter's type is part of a class hierarchy. The orchestrator is receiving the input with the type of the base class and I am pattern checking this input against the type of the two subclasses to call the durable entity in one way or another.The issue is that the serializer is not respecting the
System.Text.Json
attributes to include the type hints so theinput
received in the orchestrator doesn't have any polymorphism information/data about the types that originated it.Expected behavior
I would expect to be able to check the input of the orchestrator against the type of any of the children classes.
Actual behavior
Pattern checking the base class against any of the children classes is always false.
Relevant source code snippets
The class hierarchy
The event grid function
The orchestrator
Known workarounds
As a workaround I:
Operation
enum in the base classcontext.GetInput<WorkItemCreatedIntegrationEvent>();
orcontext.GetInput<WorkItemProgressedIntegrationEvent>();
based on the value of the Operation enumApp Details