Neville Nazerane
Neville Nazerane

Reputation: 7049

azure function: set blob filename from http request

I am trying to set an azure function to upload a blob from an HTTP request to a blob.

I was able to use the following for uploading a file with a static filename:

public static class Uploader
{
    [FunctionName("Uploader")]
    public static IActionResult Run(
    [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequest req,
    [Blob("hello/uploaded.jpg", FileAccess.Write)]Stream writer,
    TraceWriter log
    )
        {
            log.Info("trigger for image upload started...");
            if (!req.ContentType.Contains("multipart/form-data") || (req.Form.Files?.Count ?? 0) == 0)
            {
                log.Warning("no images found on upload attempt");
                return new BadRequestResult();
            }
            foreach (var file in req.Form.Files)
                file.CopyTo(writer.);

            return new OkObjectResult("Done!");
        }
}

Is there any way I could alter Blob("hello/uploaded.jpg") into something like Blob("hello/{fileName}" to get the name dynamically the HTTP request. I don't mind if it's anywhere from the head or body. I am trying to not use the whole GetBlockBlobReference process just for the dynamic file name alone.

Update I am not sure if I am missing something or looking at this problem the wrong way. For a serverless set up with a blob storage isn't an HTTP upload supposed to be an obvious and common scenario? How come there aren't any examples for this?

Upvotes: 2

Views: 1812

Answers (2)

Roman Kiss
Roman Kiss

Reputation: 8265

the following is an example with both an HttpRequestMessage and a POCO binding:

[FunctionName("Uploader")]
public static IActionResult Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] Info input, HttpRequest req,
[Blob("hello/{FileName}", FileAccess.Write)]Stream writer,
TraceWriter log
)
{
   //...
}

public class Info
{
   public string FileName { get; set; }
   //...
}

Update:

The following snippet shows an example for using an expanding HttpTrigger binding data support with a well-known properties such as headers and query, more details here:

[FunctionName("Uploader")]
public static IActionResult Run(
  [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)HtpRequest req,
  [Blob("hello/{query.filename}", FileAccess.Write)] Stream writer,
  // [Blob("hello/{headers.filename}", FileAccess.Write)] Stream writer,
  TraceWriter log)
{
   //...
}

sample of url:
http://localhost:7071/api/Uploader?filename=uploaded.jpg

Upvotes: 2

Mikhail Shilkov
Mikhail Shilkov

Reputation: 35144

The option suggested by @RomanKiss should work. Alternatively, if you want you can put filename into the function URL template:

[FunctionName("Uploader")]
public static IActionResult Run(
  [HttpTrigger(AuthorizationLevel.Function, "post", Route = "uploader/{filename}")] 
  HttpRequest req,
  string filename,
  [Blob("hello/{filename}", FileAccess.Write)] Stream writer,
  TraceWriter log)
{
   //...
}

Upvotes: 4

Related Questions