TaskOrchestrator re-serializes message payload using Newtonsoft.Json.
See original GitHub issueI get a JsonException when passing complex types from Orchestrator to Activity. The payload received in the TaskActivity is not compatible with System.Text.Json.
After investigation, it appears that the orchestrator re-serializes all messages using Newtonsoft.Json, with TypeNameHandling = TypeNameHandling.Objects
. This results in a JSON payload that is not parseable using System.Text.Json (which is default for TaskActivity payload)
The class that does the conversion: https://github.com/Azure/durabletask/blob/main/src/DurableTask.Core/Serializing/JsonDataConverter.cs
Here is a sample project to demonstrate the issue: https://github.com/ulvesked/DurablePocoPayloadSample And a corresponding SO question: https://stackoverflow.com/questions/73776121/json-serialization-fails-with-functioninputconverterexception-for-complex-types
My original payload:
{
"Name": "Test",
"Items": [{
"Id": "4b42d183-02c8-4108-b274-cde71f792832",
"Image": "xH5hV...",
"Thumbnail": "v8Tc3..."
}, {
"Id": "4eb034f6-eed0-4ad4-942d-c9bf20e465be",
"Image": "wAj...",
"Thumbnail": "juSiE",
}
]
}
The payload received in TaskActivity:
{
"Name": "Test",
"Items": [{
"$type": "DurablePocoPayloadSample.TestPayloadItem, DurablePocoPayloadSample",
"Id": "4b42d183-02c8-4108-b274-cde71f792832",
"Image": {
"$type": "System.Byte[], System.Private.CoreLib",
"$value": "xH5hV..."
},
"Thumbnail": {
"$type": "System.Byte[], System.Private.CoreLib",
"$value": "v8Tc3..."
}
}, {
"$type": "DurablePocoPayloadSample.TestPayloadItem, DurablePocoPayloadSample",
"Id": "4eb034f6-eed0-4ad4-942d-c9bf20e465be",
"Image": {
"$type": "System.Byte[], System.Private.CoreLib",
"$value": "wAj..."
},
"Thumbnail": {
"$type": "System.Byte[], System.Private.CoreLib",
"$value": "juSiE..."
}
}
]
}
Issue Analytics
- State:
- Created a year ago
- Comments:9 (1 by maintainers)
@plamber to fully replace the converter in DurableTask, there are a several locations you need to perform that:
protected set
, so you can derive another interfaceISettableDataConverter
which has a method or property to set the data converter. Make sure all your activities implement this, then add a middleware to the DTFx pipeline to retrieve the current activity, attempt a cast to this, and set it.TaskOrchestration
types, and add a new step as part of its run method to set these properties on the context before calling the derived implementation.Thanks for your comments. I have worked around the issue by using my own ObjectSerializer.
https://gist.github.com/ulvesked/44a6fc30d8fd622671343100eef8f1ae
I will keep it like this until the next preview, which hopefully has implemented the same serializer across the pipeline as @jviau wrote.