升级Azure Functions至.NET 7后Service Bus触发器函数报错及尝试解决
Azure Functions 升级到.NET7后ServiceBusReceiver参数转换错误解决方法
问题描述
升级Azure Functions到.NET7后,编译错误已通过安装NuGet包和重构代码解决,但运行函数时抛出以下错误:
Exception: Microsoft.Azure.Functions.Worker.FunctionInputConverterException: Error converting 1 input parameters for Function 'xyz': Cannot convert input parameter 'messageReceiver' to type 'Azure.Messaging.ServiceBus.ServiceBusReceiver' from type 'System.String'. Error:System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'Azure.Messaging.ServiceBus.ServiceBusReceiver'.
错误原因
.NET7的Azure Functions默认使用Isolated Worker模型,与旧版In-Process模型的绑定规则不同:旧模型中可以直接将ServiceBusReceiver作为函数参数注入,但新模型不支持这种写法,框架会尝试将其当作字符串参数反序列化,从而抛出异常。
此外,新模型中ServiceBusReceivedMessage自身已封装了消息操作方法,无需单独传入ServiceBusReceiver。
解决方案
- 移除函数参数中的
ServiceBusReceiver - 使用
ServiceBusReceivedMessage自带的方法完成消息确认/放弃操作 - 修正消息体读取的错误写法
修正后的完整代码
函数触发方法
public async Task SendOrderFunctionTrigger( [ServiceBusTrigger("%TopicName%", "%SubscriptionName%", Connection = "ServiceBusConnectionString")] ServiceBusReceivedMessage message, ILogger log) { try { // 验证消息 var (group, checkOrder) = ValidateMessage(message); // 获取消息负载 - 修正错误的流读取写法 var json = Encoding.UTF8.GetString(message.Body); // 反序列化JSON到业务类型 var orderPlaced = System.Text.Json.JsonSerializer.Deserialize<OrderPlaced>(json); switch (checkOrder) { // 业务逻辑代码 } // 标记消息为已完成 await message.CompleteAsync(); } catch (Exception ex) { log.LogError(ex, "处理ServiceBus消息时发生异常"); // 异常时可将消息移入死信队列 await message.DeadLetterAsync("处理失败", ex.Message); } }
消息验证方法
private static (Group group, CheckOrder checkOrder) ValidateMessage(ServiceBusReceivedMessage message) { // 验证Label字段 if (!message.ApplicationProperties.TryGetValue("Label", out var labelObj) || !(labelObj is string label) || string.IsNullOrEmpty(label)) throw new Exception("消息Label为空或无效"); // 验证Channel字段 if (!message.ApplicationProperties.TryGetValue("Channel", out var channelValue) || string.IsNullOrEmpty(channelValue?.ToString())) throw new Exception("消息Channel为空或无效"); // 解析Group枚举(需从ApplicationProperties获取对应字段值) if (!message.ApplicationProperties.TryGetValue("Group", out var groupValue) || !Enum.TryParse<Group>(groupValue.ToString(), out var group)) throw new Exception("消息Group字段无效"); // 解析CheckOrder枚举 string label1 = null; if (message.ApplicationProperties.TryGetValue("Label1", out var labelObj1) && labelObj1 is string labelValue) { label1 = labelValue; } if (!Enum.TryParse<CheckOrder>(label1, out var checkOrder)) throw new Exception("消息Label1字段无效,无法解析为CheckOrder枚举"); // 其他验证逻辑 return (group, checkOrder); }
关键说明
- 消息操作:新模型中直接调用
ServiceBusReceivedMessage的CompleteAsync()、DeadLetterAsync()等方法即可完成消息生命周期管理,无需依赖ServiceBusReceiver。 - 消息体读取:
ServiceBusReceivedMessage.Body是BinaryData类型,直接用Encoding.UTF8.GetString(message.Body)即可获取字符串内容,转成Stream后调用ToString()会返回流的类型名而非实际内容,属于错误写法。
内容的提问来源于stack exchange,提问作者Snevan
相关产品推荐
相关产品推荐

