本文介绍了Azure 函数应用程序:无法将队列绑定到类型“Microsoft.WindowsAzure.Storage.Queue.CloudQueue"(IBinder)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 Azure 函数方案:

My scenario for an Azure function:

  1. HTTP 触发器.
  2. 基于 HTTP 参数,我想从适当的存储队列中读取消息并将数据返回.

这是函数的代码(F#):

Here is the code of the function (F#):

let Run(request: string, customerId: int, userName: string, binder: IBinder) =
    let subscriberKey = sprintf "%i-%s" customerId userName
    let attribute = new QueueAttribute(subscriberKey)
    let queue = binder.Bind<CloudQueue>(attribute)
    () //TODO: read messages from the queue

编译成功(使用正确的 NuGet 引用和打开包),但我得到运行时异常:

The compilation succeeds (with proper NuGet references and opening packages), but I get the runtime exception:

Microsoft.Azure.WebJobs.Host:
Can't bind Queue to type 'Microsoft.WindowsAzure.Storage.Queue.CloudQueue'.

我的代码基于 这篇文章.

我做错了什么?

更新:现在我意识到我没有在任何地方指定连接名称.我是否需要绑定基于 IBinder 的队列访问?

Update: now I realize I haven't specified Connection Name anywhere. Do I need a binding for the IBinder-based queue access?

更新 2:我的 function.json 文件:

Update 2: my function.json file:

{
  "bindings": [
    {
      "type": "httpTrigger",
      "name": "request",
      "route": "retrieve/{customerId}/{userName}",
      "authLevel": "function",
      "methods": [
        "get"
      ],
      "direction": "in"
   }
 ],
 "disabled": false
}

推荐答案

我怀疑您遇到了版本控制问题,因为您引入的 Storage SDK 版本存在冲突.相反,使用内置的(不带任何 nuget 包).此代码适用于没有 project.json:

I suspect that you're having versioning issues because you're bringing in a conflicting version of the Storage SDK. Instead, use the built in one (w/o bringing in any nuget packages). This code works with no project.json:

#r "Microsoft.WindowsAzure.Storage"

open Microsoft.Azure.WebJobs;
open Microsoft.WindowsAzure.Storage.Queue;

let Run(request: string, customerId: int, userName: string, binder: IBinder) =
    async {
        let subscriberKey = sprintf "%i-%s" customerId userName
        let attribute = new QueueAttribute(subscriberKey)
        let! queue = binder.BindAsync<CloudQueue>(attribute) |> Async.AwaitTask
        () //TODO: read messages from the queue
    } |> Async.RunSynchronously

这将绑定到默认存储帐户(我们在创建函数应用时为您创建的帐户).如果要指向不同的存储帐户,则需要创建一个属性数组,并包含一个指向所需存储帐户的 StorageAccountAttribute(例如 new StorageAccountAttribute("your_storage")).然后,您将此属性数组(队列属性在数组中的第一个)传递到采用属性数组的 BindAsync 重载中.请参阅此处 了解更多详情.

This will bind to the default storage account (the one we created for you when your Function App was created). If you want to point to a different storage account, you'll need to create an array of attributes, and include a StorageAccountAttribute that points to your desired storage account (e.g. new StorageAccountAttribute("your_storage")). You then pass this array of attributes (with the queue attribute first in the array) into the BindAsync overload that takes an attribute array. See here for more details.

但是,如果您不需要进行任何复杂的解析/格式化来形成队列名称,我认为您甚至不需要为此使用 Binder.您可以完全以声明方式绑定到队列.这是 function.json 和代码:

However, if you don't need to do any sophisticated parsing/formatting to form the queue name, I don't think you even need to use Binder for this. You can bind to the queue completely declaratively. Here's the function.json and code:

{
  "bindings": [
    {
      "type": "httpTrigger",
      "name": "request",
      "route": "retrieve/{customerId}/{userName}",
      "authLevel": "function",
      "methods": [
        "get"
      ],
      "direction": "in"
    },
    {
      "type": "queue",
      "name": "queue",
      "queueName": "{customerId}-{userName}",
      "connection": "<your_storage>",
      "direction": "in"
    }
  ]
}

和函数代码:

#r "Microsoft.WindowsAzure.Storage"

open Microsoft.Azure.WebJobs;
open Microsoft.WindowsAzure.Storage.Queue;

let Run(request: string, queue: CloudQueue) =
    async {
        () //TODO: read messages from the queue
    } |> Async.RunSynchronously

这篇关于Azure 函数应用程序:无法将队列绑定到类型“Microsoft.WindowsAzure.Storage.Queue.CloudQueue"(IBinder)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-07 02:37