Azure Durable Functions调用StartNewAsync无法传入HttpRequestMessage参数
问题核心原因
HttpRequestMessage本身包含当前请求的Http上下文、依赖注入容器等大量带自引用关系的运行时对象,而Durable Functions跨编排函数传递的所有参数都需要经过JSON序列化持久化到存储,用于后续编排重放,原生的HttpRequestMessage天生不满足可序列化要求。
是否可以完全不拷贝数据直接透传?
不存在稳定可用的直接透传方案。就算通过修改序列化配置绕开自引用报错,序列化后的HttpRequestMessage里的上下文对象在请求结束后就会失效,编排重放时取到的也都是无效值,后续调用依然会出错。
两个低成本规避方案
如果不想手动定义DTO拷贝字段,可以用以下方式减少代码量:
方案1:仅提取你需要的有效字段,用匿名类传递(推荐)
不需要提前定义固定的传输类,在触发函数里直接提取需要的请求字段封装到匿名类传入即可:
[FunctionName("RequestHandler")] public static async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "RequestHandler")] HttpRequestMessage request, [DurableClient] IDurableOrchestrationClient orchestrationClient, ILogger logger) { // 仅提取实际需要用到的字段,不用拷贝所有属性 var orchestrationInput = new { RequestUri = request.RequestUri, HttpMethod = request.Method.ToString(), Headers = request.Headers.ToDictionary(kv => kv.Key, kv => kv.Value), Body = await request.Content.ReadAsStringAsync() }; var instanceId = await orchestrationClient.StartNewAsync("MakeCallout", orchestrationInput); return new AcceptedResult("", ""); }
编排侧直接按字段取值即可,不用额外定义类。
方案2:修改Durable Functions序列化配置绕开报错(不推荐)
如果一定要尝试直接传HttpRequestMessage,可以通过自定义序列化配置忽略自引用循环:
- 先添加Microsoft.Azure.Functions.Extensions包引用
- 添加项目启动配置类:
using Microsoft.Azure.Functions.Extensions.DependencyInjection; using Microsoft.Azure.WebJobs.Extensions.DurableTask; using Newtonsoft.Json; [assembly: FunctionsStartup(typeof(YourProjectNamespace.Startup))] namespace YourProjectNamespace { public class Startup : FunctionsStartup { public override void Configure(IFunctionsHostBuilder builder) { builder.Services.AddSingleton<IMessageSerializerSettingsFactory, CustomSerializerFactory>(); } } internal class CustomSerializerFactory : IMessageSerializerSettingsFactory { public JsonSerializerSettings CreateJsonSerializerSettings() { return new JsonSerializerSettings { // 忽略自引用循环 ReferenceLoopHandling = ReferenceLoopHandling.Ignore, // 空值处理可以按需加 NullValueHandling = NullValueHandling.Ignore }; } } }
注意:该方案仅能解决序列化报错问题,无法解决
HttpRequestMessage中上下文对象失效的问题,后续使用过程中大概率会出现空引用或者值异常的问题,仅做临时验证使用,不建议用于生产环境。
内容的提问来源于stack exchange,提问作者ajax2112
相关产品推荐
相关产品推荐

