在异步方法中绑定到输出 blob 时,将 Blob 绑定到 IAsyncCollector 时出错
Error binding Blob to IAsyncCollector when binding to output blob in Async method
我正在尝试按照此 post 以异步方法绑定到 blob 输出:
我有多个输出绑定,所以只返回不是一个选项
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
}
但每当我这样做时,我都会得到以下信息:
Error: Function ($WebHook) Error:
Microsoft.Azure.WebJobs.Host: Error indexing method
'Functions.WebHook'. Microsoft.Azure.WebJobs.Host: Can't bind
Blob to type
'Microsoft.Azure.WebJobs.IAsyncCollector`1[System.String]'
Blob 输出绑定不支持收集器,请参阅此 issue。
对于可变数量的输出 blob(在您的情况下为 0 或 1,但可以是任意值),您将不得不使用命令式绑定。从 function.json
中删除 collection
绑定,然后执行此操作:
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);
}
}
您可以使用 Blob-Binding。
我更喜欢这种方式,因为我可以指定 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();
}
我正在尝试按照此 post 以异步方法绑定到 blob 输出:
我有多个输出绑定,所以只返回不是一个选项
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
}
但每当我这样做时,我都会得到以下信息:
Error: Function ($WebHook) Error: Microsoft.Azure.WebJobs.Host: Error indexing method 'Functions.WebHook'. Microsoft.Azure.WebJobs.Host: Can't bind Blob to type 'Microsoft.Azure.WebJobs.IAsyncCollector`1[System.String]'
Blob 输出绑定不支持收集器,请参阅此 issue。
对于可变数量的输出 blob(在您的情况下为 0 或 1,但可以是任意值),您将不得不使用命令式绑定。从 function.json
中删除 collection
绑定,然后执行此操作:
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);
}
}
您可以使用 Blob-Binding。
我更喜欢这种方式,因为我可以指定 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();
}