bindingazure-functionsazure-blob-storageazure-functions-isolatedbinding-expressions

Set name and/or container name dynamically when using BlobOutputAttribute


I'm working on an azure function that is triggered by a service bus queue and finally posts content to a blob storage container using "BlobOutputAttribute" binding:

    [Function(nameof(Function))]
    [BlobOutput("container/test.txt", Connection = "AzureWebJobsStorage")]
    public async Task<string> Run(
        [ServiceBusTrigger("%ServicebusQueueName%", Connection = "ServicebusConnectionString")] 
        ServiceBusReceivedMessage message, 
        ServiceBusMessageActions messageActions)
    {
        try {
            logger.LogInformation("Message Body: {body}", message.Body);
    
            // Complete the message
            await messageActions.CompleteMessageAsync(message);
    
            // Send content to blob storage
            return message.Body.ToString();
        }
        catch(Exception ex) {
            logger.LogError(ex, ex.Message);
            throw;
        }
    } 

Is there a way to dynamically set the name of the container and name of the file? I've looked into "binding expression patterns", but from what I've seen in the documentation and some clips on Youtube I've only come across the {rand-guid} example which everyone quite shortly only say "it auto generates a guid". Not quite what I'm looking for.


Solution

  • You can use below code to set blob name dynamically and upload the blob to Storage container.

    You can generate blob name with Timestamp or Message ID.

    Code Snippet:

    [Function(nameof(Function1))]
    public async Task Run(
        [ServiceBusTrigger("sbqueue", Connection = "demo")]
        ServiceBusReceivedMessage message,
        ServiceBusMessageActions messageActions)
    {
        _logger.LogInformation("Message ID: {id}", message.MessageId);
        _logger.LogInformation("Message Body: {body}", message.Body);
        _logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
    
        await messageActions.CompleteMessageAsync(message);
    
        var containerName = "container";
        var connectionString = Environment.GetEnvironmentVariable("AzureWebJobsStorage");
        var blobServiceClient = new BlobServiceClient(connectionString);
        var containerClient = blobServiceClient.GetBlobContainerClient(containerName);
    
        // Generate a dynamic blob name based on message ID or timestamp
        var fileName = $"{DateTime.UtcNow}.txt";
     // var fileName = $"{Message.MessageId}.txt";
       
        var blobClient = containerClient.GetBlobClient(fileName);
        using (var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(message.Body.ToString())))
        {
            await blobClient.UploadAsync(stream, overwrite: true); 
        }
    
        _logger.LogInformation("Blob uploaded: {container}/{fileName}", containerName, fileName);
    }
    

    Using DateTime as blobname:

    Console Output:

    Functions:
    
    Function1: serviceBusTrigger
    
    For detailed output, run func with --verbose flag.  
    [2024-11-27T09:05:50.813Z] Host lock lease acquired by instance ID '0000000000000000000000000C237F69'.  
    [2024-11-27T09:06:33.092Z] Executing 'Functions.Function1' (Reason='(null)', Id=25e6a342-9ee8-427a-afc5-fd1a801d1c2f)  
    [2024-11-27T09:06:33.098Z] Trigger Details: MessageId: 9c459abdecde448aa2cd5fb00d2c7ec2, SequenceNumber: 10, DeliveryCount: 1, EnqueuedTimeUtc: 2024-11-27T09:06:29.9050000+00:00, LockedUntilUtc: 2024-11-27T09:07:29.9520000+00:00, SessionId: (null)  
    [2024-11-27T09:06:33.627Z] Message ID: 9c459abdecde448aa2cd5fb00d2c7ec2  
    [2024-11-27T09:06:33.630Z] Message Body: Hello World  
    [2024-11-27T09:06:33.635Z] Message Content-Type: (null)  
    [2024-11-27T09:06:33.676Z] Start processing HTTP request POST [http://127.0.0.1:59633/Settlement/Complete](http://127.0.0.1:59633/Settlement/Complete "http://127.0.0.1:59633/settlement/complete")  
    [2024-11-27T09:06:33.686Z] Sending HTTP request POST [http://127.0.0.1:59633/Settlement/Complete](http://127.0.0.1:59633/Settlement/Complete "http://127.0.0.1:59633/settlement/complete")  
    [2024-11-27T09:06:34.216Z] Received HTTP response headers after 513.4688ms - 200  
    [2024-11-27T09:06:34.224Z] End processing HTTP request after 556.9005ms - 200  
    [2024-11-27T09:06:35.555Z] Blob uploaded: container1/11/27/2024 9:06:34 AM.txt  
    [2024-11-27T09:06:35.627Z] Executed 'Functions.Function1' (Succeeded, Id=25e6a342-9ee8-427a-afc5-fd1a801d1c2f, Duration=2587ms)
    

    Portal:

    Blob generated with Timestamp as blob name in Storage Container.

    enter image description here

    Using MessageID as blobname:

    Console Output:

    [2024-11-27T09:28:31.101Z] Executing 'Functions.Function1' (Reason='(null)', Id=e45f0dfd-4f87-4b38-b6f4-0c277c5eb842)  
    [2024-11-27T09:28:31.107Z] Trigger Details: MessageId: f1c475407b2646a99764b6fcae4eb6f6, SequenceNumber: 13, DeliveryCount: 1, EnqueuedTimeUtc: 2024-11-27T09:28:22.2990000+00:00, LockedUntilUtc: 2024-11-27T09:29:28.0030000+00:00, SessionId: (null)  
    [2024-11-27T09:28:31.719Z] Message ID: f1c475407b2646a99764b6fcae4eb6f6  
    [2024-11-27T09:28:31.725Z] Message Body: Hello World  
    [2024-11-27T09:28:31.736Z] Message Content-Type: (null)  
    [2024-11-27T09:28:31.777Z] Start processing HTTP request POST [http://127.0.0.1:59848/Settlement/Complete](http://127.0.0.1:59848/Settlement/Complete "http://127.0.0.1:59848/settlement/complete")  
    [2024-11-27T09:28:31.790Z] Sending HTTP request POST [http://127.0.0.1:59848/Settlement/Complete](http://127.0.0.1:59848/Settlement/Complete "http://127.0.0.1:59848/settlement/complete")  
    [2024-11-27T09:28:32.261Z] Received HTTP response headers after 445.59ms - 200  
    [2024-11-27T09:28:32.269Z] End processing HTTP request after 503.7729ms - 200  
    [2024-11-27T09:28:33.490Z] Host lock lease acquired by instance ID '0000000000000000000000000C237F69'.  
    [2024-11-27T09:28:33.631Z] Blob uploaded: container1/f1c475407b2646a99764b6fcae4eb6f6.txt  
    [2024-11-27T09:28:33.692Z] Executed 'Functions.Function1' (Succeeded, Id=e45f0dfd-4f87-4b38-b6f4-0c277c5eb842, Duration=2642ms)
    

    Portal:

    Blob generated with Timestamp as blob name in Storage Container.

    enter image description here