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

.NET 8 Azure Functions隔离进程中Service Bus JObject序列化异常

问题分析与解决思路

核心问题根源

.NET 8 隔离进程模式的 Azure Functions,其绑定系统默认使用 System.Text.Json 进行对象序列化,而非你代码中依赖的 Newtonsoft.Json。你全局配置的 JsonConvert.DefaultSettings 仅对手动调用 Newtonsoft 序列化的场景生效,无法影响 Functions 绑定的自动序列化逻辑,这就导致返回的 Envelope<JObject> 在被 System.Text.Json 处理时,错误解析了 JObject 的内部结构,出现序列化不完整(表现为数组嵌套空结构)的问题。


具体解决方案

方案一:手动序列化返回字符串(快速生效)

直接将函数返回类型改为字符串,手动使用 Newtonsoft.Json 完成序列化,让 Service Bus 输出绑定直接发送已序列化好的字符串内容,绕开自动序列化的冲突:

[Function(nameof(HandleQueueA))]
[ServiceBusOutput(OutputQueueB, Connection = "ServiceBusConnection")]
public async Task<string> Run(
    [ServiceBusTrigger(StartQueueA, Connection = "ServiceBusConnection")]
    ServiceBusReceivedMessage message)
{
    var eventData = JsonConvert.DeserializeObject<Envelope<JToken>>(message.Body);

    // 业务逻辑处理

    return JsonConvert.SerializeObject(eventData);
}

方案二:配置 Functions 使用 Newtonsoft.Json 作为默认序列化器

通过扩展包让 Functions 绑定系统切换为 Newtonsoft.Json,复用你已有的全局序列化配置:

  1. 安装 NuGet 包:Microsoft.Azure.Functions.Worker.Extensions.NewtonsoftJson
  2. 在 Program.cs 中替换默认序列化器并注入你的配置:
var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(worker =>
    {
        // 启用 Newtonsoft.Json 作为绑定的默认序列化器
        worker.UseNewtonsoftJson();
    })
    .ConfigureServices(services =>
    {
        // 配置 Newtonsoft.Json 规则,与你原全局配置对齐
        services.Configure<NewtonsoftJsonSerializerOptions>(options =>
        {
            options.DefaultValueHandling = DefaultValueHandling.Include;
            options.NullValueHandling = NullValueHandling.Ignore;
            options.ContractResolver = new CamelCasePropertyNamesContractResolver();
            options.Converters.Add(new StringEnumConverter());
            options.Converters.Add(new IsoDateTimeConverter());
        });
    })
    .Build();

host.Run();

修改完成后,函数返回 Envelope<JObject> 时,输出绑定会自动使用你的 Newtonsoft 配置完成序列化,无需手动处理。

方案三:统一迁移到 System.Text.Json(长期维护)

如果愿意替换序列化引擎为官方默认的 System.Text.Json,可以做以下调整:

  1. 反序列化时使用 JsonElement 替代 JToken/JObject:
var eventData = JsonSerializer.Deserialize<Envelope<JsonElement>>(message.Body.ToString());
  1. 在 Program.cs 中配置 System.Text.Json 的全局规则,同时为自定义类型 DateTimeEpoch 编写转换器:
// 自定义 DateTimeEpoch 的 System.Text.Json 转换器
public class DateTimeEpochConverter : JsonConverter<DateTimeEpoch>
{
    public override DateTimeEpoch Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 实现反序列化逻辑
    }

    public override void Write(Utf8JsonWriter writer, DateTimeEpoch value, JsonSerializerOptions options)
    {
        // 实现序列化逻辑,对齐原 CamelCase 等规则
        writer.WriteStartObject();
        writer.WriteString("dateTime", value.DateTime.ToString("o"));
        writer.WriteNumber("epoch", value.Epoch);
        writer.WriteEndObject();
    }
}

// 全局配置
var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(worker =>
    {
        worker.UseSystemTextJson(options =>
        {
            options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
            options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
            options.Converters.Add(new JsonStringEnumConverter());
            options.Converters.Add(new DateTimeEpochConverter());
        });
    })
    .Build();

host.Run();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 08:14:55