如何通过中间件捕获ServiceBusTrigger消息并保存至日志存储
在Azure Functions中间件中捕获ServiceBusTrigger消息并保存到日志存储
我需要实现一个中间件来捕获ServiceBusTrigger的消息,将ServiceBusMessage保存到日志存储里。用中间件是最佳方案,方便在内部多个项目中复用。之前我通过Context.BindingContext.BindingData可以捕获消息,但现在这个路径取不到值了,现有代码如下:
internal class LoggingMiddleware : IFunctionsWorkerMiddleware { public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next) { foreach (var (_, value) in context.FunctionDefinition.InputBindings) { if (value.Type == "serviceBusTrigger") { var payload = GetPayload(context, value); if (payload != null) { var loggingStore = context.InstanceServices.GetRequiredService<ILoggingStore>(); loggingStore.Save(payload); } } } await next(context); } static string? GetPayload(FunctionContext context, BindingMetadata inputBindingMetadata) { if (context.BindingContext.BindingData.TryGetValue(inputBindingMetadata.Name, out var value) && value != null) { var inputValue = value.ToString(); return inputValue; } return null; } }
修复方案
在Azure Functions Isolated Worker模型中,BindingContext.BindingData不再包含完整的触发器消息内容,官方推荐使用FunctionContext的扩展方法GetInputBindingValueAsync<T>来获取绑定数据。修改后的代码可以正确捕获ServiceBus消息:
using Azure.Messaging.ServiceBus; using System.Text; internal class LoggingMiddleware : IFunctionsWorkerMiddleware { public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next) { foreach (var (bindingName, bindingMetadata) in context.FunctionDefinition.InputBindings) { if (bindingMetadata.Type == "serviceBusTrigger") { string? payload = null; // 优先尝试获取ServiceBusMessage对象,读取消息体 var serviceBusMessage = await context.GetInputBindingValueAsync<ServiceBusMessage>(bindingName); if (serviceBusMessage != null) { payload = Encoding.UTF8.GetString(serviceBusMessage.Body); } // 如果函数绑定的是字符串类型,直接获取字符串值 else { payload = await context.GetInputBindingValueAsync<string>(bindingName); } if (payload != null) { var loggingStore = context.InstanceServices.GetRequiredService<ILoggingStore>(); loggingStore.Save(payload); } } } await next(context); } }
关键说明
- 需确保项目引用
Azure.Messaging.ServiceBusNuGet包,才能使用ServiceBusMessage类型。 - 中间件会自动适配函数的绑定类型:如果函数参数是
ServiceBusMessage,则读取消息体;如果是string,则直接获取字符串内容。 GetInputBindingValueAsync<T>是Isolated Worker模式下获取输入绑定数据的标准方式,替代了旧版的BindingContext.BindingData。
内容的提问来源于stack exchange,提问作者Raphael Monteiro Nunes
相关产品推荐
相关产品推荐

