0

I am developing a set of Azure Functions to do this high-level process

  • Receive HTTP requests through Http Trigger
  • Save metadata from those requests to Table Storage
  • Generate a PDF that is uploaded to Blob storage
  • Update the record in Table Storage to contain a reference to the document

Everything works except for the last part.

When the PDF is uploaded to blob storage, we have access to the request metadata but the blob trigger only has access to the PDF Stream that was uploaded.

I've tried the following:

Document Upload

 var context = new OperationContext();
 context.UserHeaders = new Dictionary<string, string>();
 context.UserHeaders.Add("RowKey", entity.RowKey);
 context.UserHeaders.Add("PartitionKey", entity.PartitionKey);
 cloudBlockBlob.UploadFromStream(downloadedStream, operationContext: context);

Blob Trigger Private Method

public static void Run(
        [BlobTrigger(FunctionConstants.PrintSetToBlobName, Connection = ConnectionStringName)]Stream myBlob, 
        string name, 
        TraceWriter log)
{
     // code truncated for clarity
     string documentUrl = GetDocumentUrl();
     UpdateEntity(documentUrl);
}

private static void UpdateEntity(string documentUrl)
{
        // This doesn't seem like it will work
        OperationContext context = new OperationContext();
        EntityService entityService = new EntityService();

        context.UserHeaders.TryGetValue("RowKey", out string rowKey);
        context.UserHeaders.TryGetValue("PartitionKey", out string partitionKey);

        var entity = entityService.Get(rowKey, partitionKey);

        entity.DocumentUrl = documentUrl;
        entityService.Update(entity);
}

I've tried passing OperationContext directly as a parameter in the BlobTrigger.Run function but get runtime errors because it's not a valid input.

Ultimately, my question is how can I pass metadata from the CloudBlockBlob.UploadFromStream method and read it in the Blob Trigger?

1 Answer 1

2

UserHeaders sets HTTP headers for request that uploads the blob to Azure storage. These headers can't be available in the BlobTrigger, so you can't use them to pass additional parameters.

You can save PartitionKey and RowKey to the blob metadata:

cloudBlockBlob.Metadata["PartitionKey"] = entity.PartitionKey;
cloudBlockBlob.Metadata["RowKey"] = entity.RowKey;
cloudBlockBlob.SetMetadata();

And in your other function bind BlobTrigger to CloudBlockBlob

public static void Run(
    [BlobTrigger(FunctionConstants.PrintSetToBlobName, Connection = ConnectionStringName)]CloudBlockBlob cloudBlockBlob, 
    string name, 
    TraceWriter log)
{
    ...
} 

and read the metadata

cloudBlockBlob.FetchAttributes();
var partitionKey = cloudBlockBlob.Metadata["PartitionKey"];
var rowKey = cloudBlockBlob.Metadata["RowKey"];
Sign up to request clarification or add additional context in comments.

1 Comment

cloudBlockBlob.SetMetadata throws a 404 Not Found. The code works fine without it

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.