I want to create a simple Azure function which is triggered on a blob upload.
The function works correctly as expected when I run it locally. The problem is that when I publish the code with Visual Studio 2022 publish option, I get exception and the function is not executed at all. As far as I understood, the problem is that the "Stream" argument of the function cannot be binded for some strange reason.
This is the exception I get:
Error converting 1 input parameters for Function 'BlobTriggeredFunction': Cannot convert input parameter 'stream' to type 'System.IO.Stream' from type 'Microsoft.Azure.Functions.Worker.Grpc.Messages.GrpcModelBindingData'. Error:System.FormatException: Settings must be of the form "name=value". at Azure.Storage.StorageConnectionString.<>c.b__67_0(String err) at Azure.Storage.StorageConnectionString.ParseStringIntoSettings(String connectionString, Action
1 error) at Azure.Storage.StorageConnectionString.ParseCore(String connectionString, StorageConnectionString& accountInformation, Action
1 error) at Azure.Storage.StorageConnectionString.Parse(String connectionString) at Azure.Storage.Blobs.BlobServiceClient..ctor(String connectionString, BlobClientOptions options) at Microsoft.Azure.Functions.Worker.BlobStorageBindingOptions.CreateClient() in D:\a_work\1\s\extensions\Worker.Extensions.Storage.Blobs\src\Config\BlobStorageBindingOptions.cs:line 35 at Microsoft.Azure.Functions.Worker.BlobStorageConverter.CreateBlobContainerClient(String connectionName, String containerName) in D:\a_work\1\s\extensions\Worker.Extensions.Storage.Blobs\src\BlobStorageConverter.cs:line 253 at Microsoft.Azure.Functions.Worker.BlobStorageConverter.ConvertModelBindingDataAsync(Type targetType, BlobBindingData blobData) in D:\a_work\1\s\extensions\Worker.Extensions.Storage.Blobs\src\BlobStorageConverter.cs:line 118 at Microsoft.Azure.Functions.Worker.BlobStorageConverter.ConvertFromBindingDataAsync(ConverterContext context, ModelBindingData modelBindingData) in D:\a_work\1\s\extensions\Worker.Extensions.Storage.Blobs\src\BlobStorageConverter.cs:line 63
This is the function code:
public class BlobTriggeredFunction(ILogger<BlobTriggeredFunction> logger)
{
[Function(nameof(BlobTriggeredFunction))]
public async Task Run([BlobTrigger("email-attachments/{name}", Connection = "BlobStorageConnectionString")] Stream stream, string name)
{
using var blobStreamReader = new StreamReader(stream);
var content = await blobStreamReader.ReadToEndAsync();
logger.LogInformation($"C# Blob trigger function Processed blob\n Name: {name} \n Data: {content}");
}
}
This is the setup in Program.cs:
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureAppConfiguration((hostContext, config) =>
{
config.AddJsonFile("host.json");
if (hostContext.HostingEnvironment.IsDevelopment())
{
config.AddJsonFile("local.settings.json");
config.AddUserSecrets<Program>();
}
})
.ConfigureServices(services =>
{
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
})
.Build();
host.Run();
secrets.json:
{
"BlobStorageConnectionString": "xxxxxxxxxxxxxxxxxxxxxxx",
"BlobStorageConnectionString:blob": "https://xxxxxxxxxxxxxxx.blob.core.windows.net/",
"BlobStorageConnectionString:queue": "https://xxxxxxxxxxxxxxx.queue.core.windows.net/"
}
I tried changing "Stream" argument to byte[] or string, but none of that helped. I don't expect that the problem is in the connection string, because the function is triggered when I upload a blob, but it cannot be processed. The worst problem is that it happens only in Azure environment when I publish the code. It works fine in the local environment.
The problem was that I didn't add environment variables in Program.cs. Environment variables are used in the Azure portal
.ConfigureAppConfiguration( ( hostContext, config ) =>
{
config.AddJsonFile( "host.json" );
if (hostContext.HostingEnvironment.IsDevelopment())
{
config.AddJsonFile("local.settings.json");
config.AddUserSecrets<ArchiveManagerFunction>(optional: true, reloadOnChange: false);
}
config.AddEnvironmentVariables();
} )
So the solution to my problem was in this line of the code:
config.AddEnvironmentVariables();