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

如何通过中间件捕获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.ServiceBus NuGet包,才能使用ServiceBusMessage类型。
  • 中间件会自动适配函数的绑定类型:如果函数参数是ServiceBusMessage,则读取消息体;如果是string,则直接获取字符串内容。
  • GetInputBindingValueAsync<T>是Isolated Worker模式下获取输入绑定数据的标准方式,替代了旧版的BindingContext.BindingData。

内容的提问来源于stack exchange,提问作者Raphael Monteiro Nunes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 14:46:20