使用 Azure Functions v3 将消息发送到 Azure 通知中心时出现问题,Visual Studio 2019

Problems Using Azure Functions v3 to send messages to the Azure Notification Hub, with Visual Studio 2019

我在尝试创建 azure 函数以向通知中心发送消息时遇到似乎无法调试的错误。

具体来说,当我尝试 运行 部分 C# script template example - asynchronous 时。该文档引用了我构建它时生成的 function.json ,但不幸的是我在 vs2019 下没有得到它。我将设置存储在 local.settings.json 中。执行代码片段会导致错误:

[2021-01-20T19:31:16.751Z] Found C:\AnhExp\AnhExp.Function02\AnhExp.Function02.csproj. Using for user secrets file configuration.
[2021-01-20T19:31:19.066Z] Microsoft.Azure.WebJobs.Host: Error indexing method 'ANHMessage02'. Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'notification' to type IAsyncCollector`1. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).
[2021-01-20T19:31:19.133Z] Error indexing method 'ANHMessage02'
[2021-01-20T19:31:19.136Z] Microsoft.Azure.WebJobs.Host: Error indexing method 'ANHMessage02'. Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'notification' to type IAsyncCollector`1. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).
[2021-01-20T19:31:19.138Z] Function 'ANHMessage02' failed indexing and will be disabled.
[2021-01-20T19:31:19.171Z] The 'ANHMessage02' function is in error: Microsoft.Azure.WebJobs.Host: Error indexing method 'ANHMessage02'. Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'notification' to type IAsyncCollector`1. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).

错误似乎表明它无法正确绑定,但我不确定要添加哪些库或用哪些库来描述绑定。

AnhMessage02 有这个 header:

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.NotificationHubs;

...

[FunctionName("ANHMessage02")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
            IAsyncCollector<IDictionary<string, string>> notification,
            ILogger log)

我的 local.settings.json 看起来像这样:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "AzureWebJobsNotificationHubsConnectionString": "Endpoint=?;SharedAccessKeyName=?;SharedAccessKey=?"
  },
  "bindings": [
    {
      "type": "notificationHub",
      "direction": "out",
      "name": "notification",
      "tagExpression": "",
      "hubName": "?",
      "connection": "Endpoint=?;SharedAccessKeyName=?;SharedAccessKey=?",
      "platform": "apns"
    }
  ],
  "disabled": false
}

谢谢

Azure Functions 的通知中心输出绑定仅在 Azure Functions 1.x 中可用,在 Functions 2.x 及更高版本中不可用。更多详情请参考the official document

例如

  1. 安装 SDK
Install-Package Microsoft.Azure.WebJobs.Extensions.NotificationHubs -Version 1.3.0
  1. 配置连接字符串

local.setting.json

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "<language worker>",
    "AzureWebJobsStorage": "<connection-string>",
    "AzureWebJobsDashboard": "<connection-string>",
    "MyHubConnectionString": "<the connection string for the hub>",
  
  },
}
  1. 代码

 [FunctionName("Function1")]
        public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req,[NotificationHub(ConnectionStringSetting= "MyHubConnectionString", EnableTestSend =true,HubName ="hub")] IAsyncCollector<IDictionary<string, string>> notification, TraceWriter log)
        {
            log.Info("C# HTTP trigger function processed a request.");

            // parse query parameter
            string name = req.GetQueryNameValuePairs()
                .FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
                .Value;

            if (name == null)
            {
                // Get request body
                dynamic data = await req.Content.ReadAsAsync<object>();
                name = data?.name;
            }
            Dictionary<string, string> templateProperties = new Dictionary<string, string>();
            templateProperties["user"] = "A new user wants to be added : " + name;
            await notification.AddAsync(templateProperties);
            return name == null
                ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a name on the query string or in the request body")
                : req.CreateResponse(HttpStatusCode.OK, "Hello " + name);
        }