1

I have a json in an azure blob that I need to deserialize and get a string from. The string is the name of a blob. I need to then copy the blob that is the input to this function with the name I just extracted to a storage container.

public static void Run([BlobTrigger("output/{name}", Connection = "AzureWebJobsStorage")]Stream myBlob, string name, TraceWriter log)
using (var sr = new StreamReader(myBlob))
using (var jsonTextReader = new JsonTextReader(sr))
{
    var transcript = (someobject)serializer.Deserialize(jsonTextReader, typeof(Transcript));
    string blobname = (someobject.Results[0].FileName).Substring(0, name.LastIndexOf('.'));

Above is the definiton of my current function and the method I am using to extract the filename from the json. Is this possible to do with blob input and output bindings? If so, is there a way to dynamically allocate the name of the output blob?

2 Answers 2

1

You can use imperative binding to write output blob, something in lines with:

public static void Run(
    [BlobTrigger("input/{name}", Connection = "AzureWebJobsStorage")] string myBlob, 
    string name, 
    Binder binder)
{
  var someobject= serializer.Deserialize<Transcript>(myBlob);
  string blobname = (someobject.Results[0].FileName).Substring(0, name.LastIndexOf('.'));

  using (var writer = binder.Bind<TextWriter>(
              new BlobAttribute($"output/{blobname}")))
  {
      writer.Write(myBlob);
  }
}

I changed your function a bit to make my example easier to read.

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

6 Comments

the problem I am having is that the Blob is being uploaded empty to the destination blob
@DarthVeder Are you still using Streams? If so, you might copy streams incorrectly.
Yup I'm using streams.
@DarthVeder Don't forget to reset input stream to position 0 before copying to output. Or refactor to strings :)
I kept getting this error when I tried to reset the stream to 0: Object reference not set to an instance of an object
|
0

If you configure a CloudBlockBlob output binding, the Container and Name properties will be read-only, defined by the [Blob] binding attribute. However, there is something called "imperative binding" that lets you defer the binding until runtime, and the example even demonstrates writing to an arbitrary blob container and filename:

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host.Bindings.Runtime;

public static async Task Run(string input, Binder binder)
{
    using (var writer = await binder.BindAsync<TextWriter>(new BlobAttribute("samples-output/path")))
    {
        writer.Write("Hello World!!");
    }
}

For pre-compiled applications I personally find the "old fashioned way" easier to read, but I suppose it's a matter of preference.

CloudStorageAccount storage = CloudStorageAccount.Parse(conn_str);
CloudBlobClient blobClient = storage.CreateCloudBlobClient();
CloudBlobContainer blobContainer = blobClient.GetContainerReference(container);
CloudBlockBlob blob =blobContainer.GetBlockBlobReference(filename);
// etc.

Comments

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.