SB2055
SB2055

Reputation: 12862

Azure Blob Storage to host images / media - fetching with blob URL (without intermediary controller)

In this article, the author provides a way to upload via a WebAPI controller. This makes sense to me.

He then recommends using an API Controller and a dedicated service method to deliver the blob:

 public async Task<HttpResponseMessage> GetBlobDownload(int blobId)
 {
    // IMPORTANT: This must return HttpResponseMessage instead of IHttpActionResult

    try
    {
        var result = await _service.DownloadBlob(blobId);
        if (result == null)
        {
            return new HttpResponseMessage(HttpStatusCode.NotFound);
        }

        // Reset the stream position; otherwise, download will not work
        result.BlobStream.Position = 0;

        // Create response message with blob stream as its content
        var message = new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new StreamContent(result.BlobStream)
        };

        // Set content headers
        message.Content.Headers.ContentLength = result.BlobLength;
        message.Content.Headers.ContentType = new MediaTypeHeaderValue(result.BlobContentType);
        message.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = HttpUtility.UrlDecode(result.BlobFileName),
            Size = result.BlobLength
        };

        return message;
    }
    catch (Exception ex)
    {
        return new HttpResponseMessage
        {
            StatusCode = HttpStatusCode.InternalServerError,
            Content = new StringContent(ex.Message)
        };
    }
 }

My question is - why can't we just reference the blob URL directly after storing it in the database (instead of fetching via Blob ID)?

What's the benefit of fetching through a controller like this?

Upvotes: 2

Views: 125

Answers (2)

David Makogon
David Makogon

Reputation: 71030

You can certainly deliver a blob directly, which then avoids using resources of your app tier (vm, app service, etc). Just note that, if blobs are private, you'd have to provide a special signed URI to the client app (e.g. adding a shared access signature) to allow this URI to be used publicly (for a temporary period of time). You'd generate the SAS within your app tier.

You'd still have all of your access control logic in your controller, to decide who has the rights to the object, for how long, etc. But you'd no longer need to stream the content through your app (consuming cpu, memory, & network resources). And you'd still be able to use https with direct storage access.

Upvotes: 3

Graham
Graham

Reputation: 7802

Quite simply, you can enforce access control centrally when you use a controller. You have way more control over who/what/why is accessing the file. You can also log requests pretty easily too.

Longer term, you might want to change the locations of your files, add a partitioning strategy for scalability, or do something else in your app that requires a change that you don't see right now. When you use a controller you can isolate the client code from all of those inevitable changes.

Upvotes: 1

Related Questions