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

C#中如何为Azure Functions自动JSON序列化配置自定义契约解析器

解决方案:Azure Function中配置自定义契约解析器实现序列化/反序列化分离

问题背景

你在HTTP触发的Azure Function中,从SOAP服务获取XML数据反序列化为WaybillHeader对象时,依赖JsonProperty特性指定的映射名称;但返回HTTP响应时,希望用类的原始属性名(比如Id而非ID),已实现CustomContractResolver但不知道如何全局配置到自动序列化流程。

正确配置方式

根据你的Azure Functions运行模型(隔离进程/进程内),选择对应的配置方案:

1. 隔离进程模型(Isolated Worker Model)

在Program.cs中全局配置Newtonsoft.Json的序列化设置:

using Microsoft.Extensions.Hosting;
using Newtonsoft.Json.Serialization;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(builder =>
    {
        // 配置Json序列化选项
        builder.Services.Configure<Microsoft.Azure.Functions.Worker.Http.JsonOptions>(options =>
        {
            options.SerializerSettings.ContractResolver = new CustomContractResolver();
            // 添加自定义布尔转换器
            options.SerializerSettings.Converters.Add(new StrToBoolConverter());
        });
    })
    .Build();

host.Run();

2. 进程内模型(In-Process Model)

方式一:全局配置(通过Startup.cs)

创建Startup.cs注册服务,全局替换契约解析器:

using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Serialization;

[assembly: FunctionsStartup(typeof(YourFunctionApp.Startup))]
namespace YourFunctionApp
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            // 配置Mvc的NewtonsoftJson选项
            builder.Services.Configure<Microsoft.AspNetCore.Mvc.MvcNewtonsoftJsonOptions>(options =>
            {
                options.SerializerSettings.ContractResolver = new CustomContractResolver();
                options.SerializerSettings.Converters.Add(new StrToBoolConverter());
            });
        }
    }
}

方式二:手动序列化(局部生效)

如果不想全局修改,可在函数内手动序列化对象后返回:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Threading.Tasks;

[FunctionName("GetWaybill")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req)
{
    // 从SOAP服务获取并反序列化为WaybillHeader
    WaybillHeader waybill = await FetchWaybillFromSoap();

    // 使用自定义配置序列化
    var jsonSettings = new JsonSerializerSettings
    {
        ContractResolver = new CustomContractResolver(),
        Converters = new List<JsonConverter> { new StrToBoolConverter() }
    };
    string responseJson = JsonConvert.SerializeObject(waybill, jsonSettings);

    return new ContentResult
    {
        Content = responseJson,
        ContentType = "application/json",
        StatusCode = 200
    };
}

为什么之前的转换器方案无效?

你在StrToBoolConverter.WriteJson中设置serializer.ContractResolver的方式存在问题:

  • 转换器是针对单个属性的序列化逻辑,此时整个对象的序列化契约已经初始化完成,修改ContractResolver只会影响当前属性的嵌套对象,无法作用于根对象的所有属性,这就是为什么只有第一个WaybillHeader值不生效的原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 02:45:34