Azure函数:无法应用属性类“ Queue <T>”,因为它是通用的

问题描述

在一些在线示例之后,我正在使用Visual Studio Code开发Azure耐用功能。我是Azure的新手,正在适应VB.NET的C#。我已经开发了一个持久的工作功能,将数据存储在Blob表中。这是对旨在将信息放入队列的内容的略微改编。

我正在按照here的说明进行操作,并拥有我认为应该可以工作的代码,除了它可以告诉我:

Cannot apply attribute class 'Queue<T>' because it is generic

但是,我查看了其他一些示例,包括来自Microsoft的示例,并且对于键入队列没有做任何特殊的事情。显然,我丢失了一些东西。

using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Mvc;

namespace Test.Groove
{
    public static class GrooveWebhook
    {
        [FunctionName("GrooveWebhook")]
        public static async Task<List<string>> Runorchestrator(
            [orchestrationTrigger] IDurableorchestrationContext context)
        {
            var outputs = new List<string>();
            GrooveItem data = context.GetInput<GrooveItem>();  
            string res = await context.CallActivityAsync<string>("AddToQueue",data);
            return outputs;
        }
        
        [FunctionName("AddToQueue")]
        public static async Task<String> Run(
            [ActivityTrigger] GrooveItem trans,[Queue("incoming-groove-webhooks")] IAsyncCollector<GrooveItem> GrooveData,ILogger log)
        {
            await GrooveData.AddAsync (trans);
            return $"Added Groove transaction for {trans.firstname} {trans.lastname}: {trans.email}";
        }

        [FunctionName("GrooveWebhook_HttpStart")]
        public static async Task<HttpResponseMessage> HttpStart(
            [HttpTrigger(AuthorizationLevel.Anonymous,"get","post")] HttpRequestMessage req,[DurableClient] IDurableorchestrationClient starter,ILogger log)
        {
            // Function input comes from the request content.
            var data = await req.Content.ReadAsAsync<GrooveItem>();
            string instanceId = await starter.StartNewAsync("GrooveWebhook",data);
            log.Loginformation($"Started Groove webhook orchestration with ID = '{instanceId}'.");
            return starter.CreateCheckStatusResponse(req,instanceId);
        }
    }
}

现在,这是真的很奇怪的部分。我从字面上一步一步地介绍了他们的http触发器示例,代码如下,但没有相同的错误

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;

namespace My.Functions
{
    public static class HttpExample
    {
        [FunctionName("HttpExample")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous,"post",Route = null)] HttpRequest req,[Queue("outqueue"),StorageAccount("AzureWebJobsstorage")] ICollector<string> msg,ILogger log)
        {
            log.Loginformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            string responseMessage = string.IsNullOrEmpty(name)
                ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                : $"Hello,{name}. This HTTP triggered function executed successfully.";

            return new OkObjectResult(responseMessage);
        }
    }
}

然后,好像还不够奇怪,我回到了将数据添加到表中的原始项目,并添加了这个小的队列绑定语句,而没有错误!太疯狂了代码开始:

using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Mvc;

namespace Company.Function
{
    public static class GrooveorchestrationTest
    {
        [FunctionName("GrooveorchestrationTest")]
        public static async Task<List<string>> Runorchestrator(
            [orchestrationTrigger] IDurableorchestrationContext context,[Table ("GrooveData")] IAsyncCollector<GrooveItem> GrooveData,[Queue ("GrooveQueue")] IAsyncCollector<GrooveItem> GrooveQueue)

后一种解决方案中都没有其他using指令可成功绑定队列以进行输出

另外一个想法 即使完全没有问题,我还是从头开始创建了另一个版本,完全解决了同样的问题。我对此没有任何解释。但是,我会注意到它们已连接到不同的Azure帐户。两者都是免费的,都在最近几天注册。我无法理解为什么这很重要,但这就是我能想到的。

解决方法

此问题是由VS Code自动将以下参考添加到.csproj文件中引起的:

<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.7" />

通过将其更改为与完全相同的代码可以完美工作的其他解决方案中的引用匹配来确认:

<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.3" />

参考此更改后,它可以按预期工作。

导致我这样做的原因是,从几天前粘贴到较早的解决方案中后,我的队列绑定就可以正常工作,但是在新解决方案中却无法使用完全相同的代码。为确保所有内容均相等,我粘贴了.cs文件的全部内容,因此没有区别。即旧的解决方案和新的解决方案具有相同的.cs文件,但一种有效,而一种无效。

由于我的代码在两个解决方案中都是相同的,因此很明显,VS Code必须在幕后完成某些工作。我对旧解决方案和新解决方案之间的所有自动生成的文件进行了凝视和比较。我发现此参考文献实际上是两种解决方案之间的区别,当我将其更改为较旧的版本时,一切运行正常。

我现在将参考较旧的软件包,以便能够完成此工作,然后在有空闲时间时找出如何使新SDK.Functions满意。

,

您可能缺少对Microsoft.Azure.WebJobs.Extensions.Storage的引用。