1

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.

2
  • Did you try setting the blobname manually like var fileName = $"{Guid.NewGuid()}.txt";? Commented Nov 27, 2024 at 3:50
  • @PravallikaKV not quite sure if that works as using the BlobOutputBinder attribute requires one to specify the name in the attribute itself together with the container as shown in the example above: "container/test.txt", "text.txt" being the filename. So how does one pass a name to the attribute dynamically? Commented Nov 28, 2024 at 8:28

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

5 Comments

Yeah this is the way I've done it before in my projects but this time I wanted to use the BlobOutputBinder way of posting a blob to my blob storage.
I have tested the same using BlobOutputBinder, but it accepts only constant values like sample.txt and doesn't accept the expressions such as DateTime.UtcNow.
Okey, hmm well I'll look into the matter a bit more if not I think I'll return to the traditional way of doing stuff. Thank you.
@H4p7ic: Good to accept the solution if it has helped. This is for the benefit of the SO Community, refer SO link
I accepted the only answer to this thread, its not the solution to the specific question as the answer to that is upvoted in the comments, that is - there is no solution to the question. But the answer given is at least a way to handle blobs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.