Azure 持久函数:JsonSerializationException 通过将复杂对象从触发器传递到协调器
Azure Durable Function: JsonSerializationException by passing complex object from trigger to orchestrator
我有一个带有 EventHubTrigger 的 azure 函数:
[FunctionName("TradesDataProcessStarterEh")]
public static async Task TradesDataProcessStarterEh([EventHubTrigger("aeehrobotronapiintegrationdev", Connection = "EventHubConnectionString", ConsumerGroup = "$Default")]
EventData eventData, PartitionContext partitionContext, [OrchestrationClient] DurableOrchestrationClient starter, ILogger log)
{
if (partitionContext.PartitionId != "1")
return;
var orchestrationId = await starter.StartNewAsync("O_ProcessTradesFromEventHub", eventData);
await partitionContext.CheckpointAsync();
}
协调器函数正在接收事件数据:
[FunctionName("O_ProcessTradesFromEventHub")]
public static async Task ProcessTradesFromEventHub([OrchestrationTrigger] DurableOrchestrationContext context,
ILogger log)
{
if (!context.IsReplaying)
Console.WriteLine("O_ProcessTradesFromEventHub is triggered");
var eventData = context.GetInput<EventData>();
//do stuff...
}
但是通过执行 context.GetInput() 我得到一个异常:
Function 'O_ProcessTradesFromEventHub (Orchestrator)' failed with an error. Reason: Newtonsoft.Json.JsonSerializationException: Unable to find a constructor to use for type Microsoft.Azure.EventHubs.EventData. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'Body', line 1, position 81.
我可以想到 3 种可能的解决方案,您可以尝试:
- 1 - 使用构造函数(可能通过继承?)将 EventData 包装在您自己的 class 中。
- 2 - 尝试转换为对象,怀疑这是否有效,但值得一试,因为这是一个简单的修复。
- 3 - 构建您自己的 DTO(数据传输对象)以将 EventData 转换为
<your class>
,然后将 <your class>
传递给编排。
我认为 (3) 是最简洁的解决方案,您可以完全控制传递的内容,不幸的是,它可能是性能最低且最乏味的。
祝你好运!
使用 LINQ JSON - 一年后,但希望它能为其他人节省一些时间。
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public static async Task Run(
[OrchestrationTrigger] DurableOrchestrationContext context, ILogger log) {
var eventData = context.GetInput<JObject>();
log.LogInformation ($"Executing tasks with eventData = {eventData}");
string step = (string)eventData.SelectToken("Step");
log.LogInformation ($"Step = {step}");
}
我有一个带有 EventHubTrigger 的 azure 函数:
[FunctionName("TradesDataProcessStarterEh")]
public static async Task TradesDataProcessStarterEh([EventHubTrigger("aeehrobotronapiintegrationdev", Connection = "EventHubConnectionString", ConsumerGroup = "$Default")]
EventData eventData, PartitionContext partitionContext, [OrchestrationClient] DurableOrchestrationClient starter, ILogger log)
{
if (partitionContext.PartitionId != "1")
return;
var orchestrationId = await starter.StartNewAsync("O_ProcessTradesFromEventHub", eventData);
await partitionContext.CheckpointAsync();
}
协调器函数正在接收事件数据:
[FunctionName("O_ProcessTradesFromEventHub")]
public static async Task ProcessTradesFromEventHub([OrchestrationTrigger] DurableOrchestrationContext context,
ILogger log)
{
if (!context.IsReplaying)
Console.WriteLine("O_ProcessTradesFromEventHub is triggered");
var eventData = context.GetInput<EventData>();
//do stuff...
}
但是通过执行 context.GetInput() 我得到一个异常:
Function 'O_ProcessTradesFromEventHub (Orchestrator)' failed with an error. Reason: Newtonsoft.Json.JsonSerializationException: Unable to find a constructor to use for type Microsoft.Azure.EventHubs.EventData. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'Body', line 1, position 81.
我可以想到 3 种可能的解决方案,您可以尝试:
- 1 - 使用构造函数(可能通过继承?)将 EventData 包装在您自己的 class 中。
- 2 - 尝试转换为对象,怀疑这是否有效,但值得一试,因为这是一个简单的修复。
- 3 - 构建您自己的 DTO(数据传输对象)以将 EventData 转换为
<your class>
,然后将<your class>
传递给编排。
我认为 (3) 是最简洁的解决方案,您可以完全控制传递的内容,不幸的是,它可能是性能最低且最乏味的。
祝你好运!
使用 LINQ JSON - 一年后,但希望它能为其他人节省一些时间。
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public static async Task Run(
[OrchestrationTrigger] DurableOrchestrationContext context, ILogger log) {
var eventData = context.GetInput<JObject>();
log.LogInformation ($"Executing tasks with eventData = {eventData}");
string step = (string)eventData.SelectToken("Step");
log.LogInformation ($"Step = {step}");
}