I'm following an Azure training course on LinkedIn: "Building a web application on Microsoft Azure"
I encountered an error in a section on writing an Azure function triggered by adding a file to Blob storage.
I looked up similar code in Microsoft's documentation. Writing to stream
Neither the course code or Microsoft's code work.
When I do this:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.WebJobs;
namespace Wpm
{
public class ThumbnailCreator
{
[Function(nameof(ThumbnailCreator))]
public static async Task Run(
[Microsoft.Azure.Functions.Worker.BlobTrigger("photos/{name}", Connection =
"WpmStorage")]
Stream blobStream1,
[Microsoft.Azure.WebJobs.Blob("thumbnails/{name}", FileAccess.Write,
Connection = "WpmStorage")]
Stream blobStream2)
{
await blobStream1.CopyToAsync(blobStream2);
}
}
}
I get these errors:
Executing 'Functions.ThumbnailCreator' (Reason='New blob detected(LogsAndContainerScan): photos/Kitty's cat.jpg', Id=63e38cc0-7b4d-476f-9b2c-55d1b1098bfd)
Function 'ThumbnailCreator', Invocation id '63e38cc0-7b4d-476f-9b2c-55d1b1098bfd': An exception was thrown by the invocation.
Result: Function 'ThumbnailCreator', Invocation id '63e38cc0-7b4d-476f-9b2c-55d1b1098bfd': An exception was thrown by the invocation. Exception: System.ArgumentNullException: Value cannot be null. (Parameter 'destination')
at System.ArgumentNullException.Throw(String paramName)
at System.IO.Stream.ValidateCopyToArguments(Stream destination, Int32 bufferSize)
Executed 'Functions.ThumbnailCreator' (Failed, Id=63e38cc0-7b4d-476f-9b2c-55d1b1098bfd, Duration=129ms)
[2024-09-06T12:30:37.733Z] at System.IO.Stream.CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
[2024-09-06T12:30:37.735Z] System.Private.CoreLib: Exception while executing function: Functions.ThumbnailCreator. System.Private.CoreLib: Result: Failure Exception: System.ArgumentNullException: Value cannot be null. (Parameter 'destination')
[2024-09-06T12:30:37.736Z] at System.IO.Stream.CopyToAsync(Stream destination)
[2024-09-06T12:30:37.739Z] at System.ArgumentNullException.Throw(String paramName)
[2024-09-06T12:30:37.740Z] at Wpm.ThumbnailCreator.Run(Stream blobStream1, Stream blobStream2) in F:\Code_Library_Local\Azure Course\wpm-thumbnailcreator\Thumbnailcreator\ThumbnailCreator.cs:line 21
Which I believe means that blobStream2 is Null.
And when I use Breakpoints blobStream2 is indeed Null.
But the code in my course and the code at Microsoft imply that blobStream2 is created as not Null in the method signature.
I can't find any mention of how to initialize blobStream2.
Am I right in my analysis?
What can I do about it?
There are two different packages available for 2 function types:- 1. In-process Function (Microsoft.Azure.WebJobs.Extensions.*), 2. Isolated Function (Microsoft.Azure.Functions.Worker.Extensions.*). In your code, you have created an isolated function but using output binding attribute of in-process function.
I have used given code to copy the blob using output binding of isolated function.
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
namespace _78957236
{
public class ThumbnailCreator
{
private readonly ILogger<ThumbnailCreator> _logger;
public ThumbnailCreator(ILogger<ThumbnailCreator> logger)
{
_logger = logger;
}
[Function(nameof(ThumbnailCreator))]
public async Task<MyOutputType> Run([BlobTrigger("samples-workitems/{name}", Connection = "BlobConnectionString")] Stream stream,
FunctionContext context)
{
var logger = context.GetLogger<ThumbnailCreator>();
var result = new MyOutputType();
using (MemoryStream ms = new MemoryStream())
{
await stream.CopyToAsync(ms);
result.Blob = ms.ToArray();
}
result.LogMessage = "Blob sample-container/sample-blob has been copied to the output blob.";
logger.LogInformation(result.LogMessage);
return result;
}
}
public class MyOutputType
{
[BlobOutput("test-samples-output/sample-blob", Connection = "BlobConnectionString")]
public byte[]? Blob { get; set; }
public string? LogMessage { get; set; }
}
}
.csproj-
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>_78957236</RootNamespace>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.21.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.1.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.2.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs" Version="6.3.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.17.0" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
</ItemGroup>
</Project>
I am getting expected response.
Azure Functions Core Tools
Core Tools Version: 4.0.5907 Commit hash: N/A +807e89766a92b14fd07b9f0bc2bea1d8777ab209 (64-bit)
Function Runtime Version: 4.834.3.22875
[2024-09-06T14:31:02.671Z] Found C:\Users\****\78957236\78957236.csproj. Using for user secrets file configuration.
[2024-09-06T14:31:06.288Z] Azure Functions .NET Worker (PID: 27636) initialized in debug mode. Waiting for debugger to attach...
[2024-09-06T14:31:06.341Z] Worker process started and initialized.
Functions:
ThumbnailCreator: blobTrigger
For detailed output, run func with --verbose flag.
[2024-09-06T14:31:11.334Z] Host lock lease acquired by instance ID '0000000000000000000000000D2022A4'.
[2024-09-06T14:31:20.014Z] Executing 'Functions.ThumbnailCreator' (Reason='New blob detected(LogsAndContainerScan): samples-workitems/78951632.html', Id=f73379f4-fd4d-4431-8e88-2ce9faa0eab1)
[2024-09-06T14:31:20.017Z] Trigger Details: MessageId: 54f55b73-4d21-4eac-af62-04e9b7740bea, DequeueCount: 1, InsertedOn: 2024-09-06T14:31:19.000+00:00, BlobCreated: 2024-09-06T13:38:40.000+00:00, BlobLastModified: 2024-09-06T14:31:17.000+00:00
[2024-09-06T14:31:21.845Z] Blob sample-container/sample-blob has been copied to the output blob.
[2024-09-06T14:31:23.591Z] Executed 'Functions.ThumbnailCreator' (Succeeded, Id=f73379f4-fd4d-4431-8e88-2ce9faa0eab1, Duration=3841ms)
You need to create an in-process function if you would like to use its binding attributes. Please refer to the MS Doc for the same.