Search code examples
.netazureazure-storageazure-blob-storageazure-sdk-.net

Azure Blob Storage SDK v12 - BlobClient DownloadAsync gone?


I have production code that uses the BlobClient.DownloadAsync() method to download a file from Azure Blob Storage using the Azure.Storage.Blobs nuget package v12.8, and it seems to be working just fine. However, I upgraded the nuget package and was about to write some new code to deal with zip files, that also relies on downloading in order to extract the zip...but noticed some changes in the latest APIs of the Storage SDK.

Apart from nearly EVERY sample from Microsoft, as well as from the interwebs, being slightly incorrect since that method wraps the returned BlobDownloadInfo into a Response<T> object - forcing you to do a call to .Value first, they also seem to use the above method to download blob files - BUT I can no longer find that method via Intellisense.

When I looked at the source which takes me to BlobBaseClient.DownloadAsync() method, I see that it is decorated with [EditorBrowsable(EditorBrowsableState.Never)], implying that this API might slowly be taken away via hiding it from devs, but without breaking existing code or marking as Obsolete. But I can't find any articles/issues/docs that point to that for sure. Here's what that looks like:

decompiled BlobBaseClient.DownloadAsync()

With that being said.....what is THE way someone should be downloading files from Azure Blob Storage (block blobs) using the .NET SDK as of v12.9, in an asynchronous fashion, if the goal is to "stream" it down thru an ASP.NET controller action (REST endpoint) to a client like a browser, etc. (NOT save to a local file on server)?

There seems to be several available "download" APIs on the BlobClient, but their docs are somewhat vague or ambiguous and the MS Docs don't seem to clarify any further:

  • DownloadAsync() - marked as not browsable, but de facto way, based on all samples/blogs
  • DownloadStreamingAsync()
  • DownloadContentAsync()
  • DownloadToAsync()
  • OpenReadAsync()

Additionally, if trying to do some other operation that is not downloading to a browser client via a REST API, for example, if you're unzipping a blob file and the extracted files are also going into blob storage, would one be better not downloading but instead opening it via OpenReadAsync()?


Solution

  • For anyone else coming to this trying to figure out how to stream/download files from Azure blob storage into an object,the OP Github issue is the best documentation I have come across.

    In short the main methods to use:

    DownloadContentAsync() - preferred way to fetch blobs that fit in memory
    DownloadStreamingAsync() - stream when bandwidth adequate (otherwise OpenReadAsync)
    OpenReadAsync() - fetches buffered chunks when bandwidth inadequate or consumer slow (otherwise DownloadStreamingAsync)
    

    Do not use:

    DownloadAsync() - replaced by DownloadStreamingAsync()
    

    When you simply want to download a file from blob storage:

    DownloadToAsync() - downloads a blob using parallel requests, and writes the content to destination
    

    DownloadContentAsync is very useful.

    For JSON files and other small blobs this conveniently provides the data as BinaryData allowing you to easily retrieve commonly used primitives (string, streams, bytes).

    Example:

    BlobContainerClient containerClient = new BlobContainerClient(_settings.ConnectionString, _settings.ContainerName);
        
    var blobClient = containerClient.GetBlobClient($"{folderName}/{fileName}");
        
    BlobDownloadResult download = await blobClient.DownloadContentAsync();
        
    MyJSONData json = download.Content.ToObjectFromJson<MyJSONData>();