You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Functions(.NET 6进程外)Durable函数复杂类型序列化失败:FunctionInputConverterException及JsonException问题求助

Fixing JSON Serialization Conflict Between Durable Task Orchestrator and Activity in .NET 6 Isolated Model

Hey fellow .NET Durable Functions dev, I just worked through exactly this serialization headache with the .NET 6 isolated (out-of-process) model, so let me break down what's going on and how to fix it.

The Problem You're Facing

  • You're building a Durable Function using the .NET 6 isolated process model
  • When passing a complex type that includes a byte[] (or other array type) from your TaskOrchestrator to a TaskActivity, you hit a JsonException
  • The error looks like this:

System.Text.Json.JsonException: 'The JSON value could not be converted to System.Byte[]. Path: $.Items[0].Image | LineNumber: 0 | BytePositionInLine: 155.'

What's Causing It?

The root issue is a serialization mismatch between the orchestrator and activity:

  • Under the hood, the Durable Task orchestrator uses Newtonsoft.Json for message replay, and it automatically adds a $type property to serialized complex objects (like {"$type":"YourNamespace.YourType, YourAssembly", ...})
  • But the activity function defaults to using System.Text.Json for deserialization, which doesn't recognize this $type-annotated format—especially not for array types like byte[], which expect a JSON array, not an object with type metadata.

Proven Fixes

1. Globally Switch the Activity to Use Newtonsoft.Json

The most straightforward fix is to configure your activity function's pipeline to use Newtonsoft.Json instead of System.Text.Json, matching what the orchestrator uses. Here's how to do it in your Program.cs:

// Make sure you have the Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet package installed
builder.Services.AddControllers().AddNewtonsoftJson(options =>
{
    // Enable TypeNameHandling to match the orchestrator's serialization behavior
    options.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
});

This lets the activity correctly parse the $type metadata that the orchestrator adds.

2. Use a Custom Input Binding Converter

If you don't want to replace the serializer globally, you can create a custom input binding converter that uses Newtonsoft.Json specifically for your Durable Activity inputs. This keeps the rest of your app on System.Text.Json while handling the Durable payloads correctly.

3. Work Around the Mismatch by Converting Arrays to Strings

A quick (but less clean) workaround is to avoid passing raw arrays directly. In the orchestrator, convert your byte[] to a Base64 string, then convert it back to a byte array in the activity:

  • Orchestrator side:
    var yourModel = new YourComplexType
    {
        Image = Convert.ToBase64String(yourRawImageBytes)
    };
    await context.CallActivityAsync("YourActivity", yourModel);
    
  • Activity side:
    public async Task Run([ActivityTrigger] YourComplexType input)
    {
        var imageBytes = Convert.FromBase64String(input.Image);
        // Rest of your logic
    }
    

Heads Up

This is a known compatibility issue in the Durable Task framework, with an active issue tracking it for a potential official fix down the line.

内容的提问来源于stack exchange,提问作者ulvesked

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 14:57:46