在Async方法中绑定到输出blob时,将Blob绑定到IAsyncCollector时出错

时间:2017-06-21 08:41:57

标签: c# azure asynchronous azure-storage-blobs azure-functions

我试图在此帖子之后尝试绑定到Async方法中的blob输出: How can I bind output values to my async Azure Function?

我有多个输出绑定,所以只返回不是一个选项

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, IAsyncCollector<string> collection, TraceWriter log)
{
    if (req.Method == HttpMethod.Post) 
    {
        string jsonContent = await req.Content.ReadAsStringAsync();

        // Save to blob 
        await collection.AddAsync(jsonContent);

        return req.CreateResponse(HttpStatusCode.OK);
    }
    else 
    {
        return req.CreateResponse(HttpStatusCode.BadRequest);

    }
}

我对blob的绑定是:

{
  "bindings": [
    {
      "authLevel": "function",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in"
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    },
    {
      "type": "blob",
      "name": "collection",
      "path": "testdata/{rand-guid}.txt",
      "connection": "test_STORAGE",
      "direction": "out"
    }
  ],
  "disabled": false
}

但每当我这样做时,我得到以下内容:

  

错误:函数($ WebHook)错误:   Microsoft.Azure.WebJobs.Host:错误索引方法   &#39; Functions.WebHook&#39 ;. Microsoft.Azure.WebJobs.Host:无法绑定   Blob要输入   &#39; Microsoft.Azure.WebJobs.IAsyncCollector`1 [System.String]&#39;

2 个答案:

答案 0 :(得分:5)

Blob输出绑定不支持收集器,请参阅此issue

对于可变数量的输出blob(在您的情况下为0或1,但可以是任何),您将不得不使用命令式绑定。从collection删除function.json绑定,然后执行此操作:

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, Binder binder)
{
    if (req.Method == HttpMethod.Post) 
    {
        string jsonContent = await req.Content.ReadAsStringAsync();

        var attributes = new Attribute[]
        {    
            new BlobAttribute("testdata/{rand-guid}.txt"),
            new StorageAccountAttribute("test_STORAGE")
        };

        using (var writer = await binder.BindAsync<TextWriter>(attributes))
        {
            writer.Write(jsonContent);
        }

        return req.CreateResponse(HttpStatusCode.OK);
    }
    else 
    {
        return req.CreateResponse(HttpStatusCode.BadRequest);    
    }
}

答案 1 :(得分:0)

您可以使用Blob绑定。

我更喜欢这种方式,因为我可以指定ContentType。

 [FunctionName(nameof(Store))]
    public static async Task<IActionResult> Store(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
        [Blob(
            "firstcontainer",
            FileAccess.Read,
            Connection = "blobConnection")] CloudBlobContainer blobContainer,
        ILogger log)
    {
        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();

        string filename = "nextlevel/body.json";

        CloudBlockBlob blob = blobContainer.GetBlockBlobReference($"{filename}");
        blob.Properties.ContentType = "application/json";
        await blob.UploadTextAsync(requestBody);

        return (ActionResult)new OkResult();
    }