使用Servicebus触发器的Azure Function Blob输入绑定

时间:2019-04-30 07:58:48

标签: c# azure azure-functions serverless

我正在尝试创建一个在AZ ServiceBus队列消息上触发的Azure函数。该消息包含一个GUID字符串,与AZ存储上的BLOB名称匹配。我想通过输入绑定获得该BLOB,但是我不确定如何...

我尝试过:

public static async Task Run(
   [ServiceBusTrigger("outgoing-mail", Connection = "QueueConnString")] string inputMessage,
   [Blob("email-messages/{inputMessage}", FileAccess.Read)] Stream mailBlob,
   [SendGrid(ApiKey = "%SendgridApiKey%")] IAsyncCollector<SendGridMessage> messageCollector,
   ILogger log)

我还在Blob路径上尝试了{serviceBusTrigger},但是无论哪种方式,我都会遇到以下异常:

  

Microsoft.Azure.WebJobs.Host:错误索引方法   “ SendMailQueueWorker”。 Microsoft.Azure.WebJobs.Host:无法解析   绑定参数“ inputMessage”。绑定表达式必须映射到   触发器提供的值或该值的属性   触发器绑定到系统绑定表达式或必须是系统绑定表达式(例如   sys.randguid,sys.utcnow等)。

我确定队列的输入消息是一个字符串,如何在BLOB的输入绑定中使用此消息内容?

[edit]
我已将功能请求添加到UserVoice,因此如果您也遇到此问题,请投票! https://feedback.azure.com/forums/355860-azure-functions/suggestions/37528912-combine-servicebus-queue-message-with-storage-inpu
[/ edit]

2 个答案:

答案 0 :(得分:2)

服务总线触发器不像队列触发器那样支持这种方式。
您可以为此在UserVoice上提出功能请求。

但是要注意的一件事是,此限制仅对非JSON消息保留 。如果您改为发送JSON消息,它将被解析为documented

您的功能可能是这样的

using System;
using System.IO;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace funk_csharp_queue
{
  public class QueueMsg
  {
    public string filename { get; set; }
  }
  public static class ServiceBusTrigger
  {
    [FunctionName("ServiceBusTrigger")]
    public static void Run(
      [ServiceBusTrigger("myqueue", Connection = "ServiceBusConnection")] QueueMsg myQueueItem,
      [Blob("samples-workitems/{filename}", FileAccess.Read)] String myBlob,
      ILogger log)
    {
      log.LogInformation($"C# Service Bus trigger function processed: {JsonConvert.SerializeObject(myQueueItem)}");
      log.LogInformation($"C# Blob input read: {myBlob}");
    }
  }
}

您在服务总线队列/主题中发送的消息将是这样

{
  "filename": "11c8f49d-cddf-4b82-a980-e16e8a8e42f8.json"
}

确保将Content Type设置为application/json

答案 1 :(得分:0)

我认为这不是您想直接实现的。我只会使用CloudBlobContainer input binding来解决此问题。

[Blob("email-messages", FileAccess.Read, Connection = "BlobConnectionString")] CloudBlobContainer blobContainer

然后使用blobContainer通过inputMessage读取函数中的blob。

CloudBlob mailBlob = blobContainer.GetBlobReference(inputMessage);