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
相关产品推荐
相关产品推荐

