-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Uploading migration guide and updating README with blog post link #13159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,272 @@ | ||||||||||||||||||||||||||||||||||||||||||||
| # Guide for migrating to Azure.Storage.Blobs from Microsoft.Azure.Storage.Blob | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| This guide intends to assist customers in migrating from version 11 of the Azure Storage .NET library for Blobs to version 12. | ||||||||||||||||||||||||||||||||||||||||||||
| It will focus on side-by-side comparisons for similar operations between the v12 package, [`Azure.Storage.Blobs`](https://www.nuget.org/packages/Azure.Storage.Blobs) and v11 package, [`Microsoft.Azure.Storage.Blob`](https://www.nuget.org/packages/Microsoft.Azure.Storage.Blob/). | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| Familiarity with the v11 client library is assumed. For those new to the Azure Storage Blobs client library for .NET, please refer to the [Quickstart](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-dotnet) for the v12 library rather than this guide. | ||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove en-us |
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ## Table of contents | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| - [Migration benefits](#migration-benefits) | ||||||||||||||||||||||||||||||||||||||||||||
| - [General changes](#general-changes) | ||||||||||||||||||||||||||||||||||||||||||||
| - [Authentication](#authentication) | ||||||||||||||||||||||||||||||||||||||||||||
| - [Package and namespaces](#package-and-namespaces) | ||||||||||||||||||||||||||||||||||||||||||||
| - [Client hierarchy](#client-hierarchy) | ||||||||||||||||||||||||||||||||||||||||||||
| - [Client constructors](#client-constructors) | ||||||||||||||||||||||||||||||||||||||||||||
| - [Migration samples](#migration-samples) | ||||||||||||||||||||||||||||||||||||||||||||
| - [Creating a Container](#creating-a-container) | ||||||||||||||||||||||||||||||||||||||||||||
| - [Uploading Blobs to a Container](#uploading-blobs-to-a-container) | ||||||||||||||||||||||||||||||||||||||||||||
| - [Downloading Blobs from a Container](#downloading-blobs-from-a-container) | ||||||||||||||||||||||||||||||||||||||||||||
| - [Listing Blobs in a Container](#listing-blobs-in-a-container) | ||||||||||||||||||||||||||||||||||||||||||||
| - [Other](#other) | ||||||||||||||||||||||||||||||||||||||||||||
| - [Additional samples](#additional-samples) | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ## Migration benefits | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| To understand why we created our version 12 client libraries, you may refer to the Tech Community blog post, [Announcing the Azure Storage v12 Client Libraries](https://techcommunity.microsoft.com/t5/azure-storage/announcing-the-azure-storage-v12-client-libraries/ba-p/1482394). | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| In summary, the v12 client libraries for Azure Storage were created in order to address a number of areas of feedback. One of the most important being that Azure services have not been consistent in organization, naming, and API structure. Azure Storage has aligned with a set of common guidelines in order to focus on quick delivery of service features and to optimize the learning curve that comes with using the libraries. They are idiomatic, approachable, and consistent. The version 12 client libraries are also thread safe, offer both synchronous and asynchronous APIs, and have improved performance over previous versions. We have reached feature parity for major scenarios and have updated documentation featuring the v12 [Quickstart](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-dotnet), [Samples](https://docs.microsoft.com/en-us/azure/storage/common/storage-samples-dotnet?toc=/azure/storage/blobs/toc.json), and [Reference](https://docs.microsoft.com/en-us/dotnet/api/azure.storage.blobs?view=azure-dotnet) pages (for .NET Azure Storage Blob Library). | ||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider linking to intro video "Introducing the new Azure SDKs" https://aka.ms/azsdk/intro |
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| Note: The blog post linked above announces deprecation for previous versions of the library. | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+26
to
+30
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Less is more. I would approach this section differently. Rather than writing an essay on the topic of benefits, would make is a list. E.g.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ## General changes | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ### Package and namespaces | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| Package names and the namespaces root for version 12 Azure client libraries follow the pattern `Azure.[Area].[Service]` where the legacy libraries followed the pattern `Microsoft.Azure.[Area].[Service]`. | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| In this case, to install the legacy v11 package with Nuget: | ||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
| dotnet add package Azure.Storage.Blobs | ||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+38
to
+41
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You've confused the two. Imagine how confused are customers with 11->12 on a different package name 😀
Suggested change
dotnet add package Microsoft.Azure.Storage.Blob |
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| It is now the following for v12: | ||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
| dotnet add package Microsoft.Azure.Storage.Blob | ||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ### Authentication | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| #### Managed Identity | ||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is such a critical area. When do you think TODO will be completed? |
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| Legacy (v11) | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| TODO | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| v12 | ||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could link to the docs for now. |
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| TODO | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| #### SAS | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| There are various SAS tokens that may be generated. Visit our documentation pages to learn how to [Create a User Delegation SAS](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-user-delegation-sas-create-dotnet), [Create a Service SAS](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-service-sas-create-dotnet), or [Create an Account SAS](https://docs.microsoft.com/en-us/azure/storage/common/storage-account-sas-create-dotnet?toc=/azure/storage/blobs/toc.json). | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| Legacy (v11) | ||||||||||||||||||||||||||||||||||||||||||||
| ```c | ||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||||||||||||||||||||||||||||||||||
| TODO | ||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| v12 | ||||||||||||||||||||||||||||||||||||||||||||
| ```c | ||||||||||||||||||||||||||||||||||||||||||||
| // This code snippet creates a service level SAS that only allows reading | ||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the paragraph above, it's stated that there are 3 way to construct a SAS token and only one snippet for all three options? This is confusing to say the least. |
||||||||||||||||||||||||||||||||||||||||||||
| // from service level APIs | ||||||||||||||||||||||||||||||||||||||||||||
| AccountSasBuilder sas = new AccountSasBuilder | ||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||
| // Allow access to blobs | ||||||||||||||||||||||||||||||||||||||||||||
| Services = AccountSasServices.Blobs, | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // Allow access to the service level APIs | ||||||||||||||||||||||||||||||||||||||||||||
| ResourceTypes = AccountSasResourceTypes.Service, | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // Access expires in 1 hour! | ||||||||||||||||||||||||||||||||||||||||||||
| ExpiresOn = DateTimeOffset.UtcNow.AddHours(1) | ||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||
| // Allow read access | ||||||||||||||||||||||||||||||||||||||||||||
| sas.SetPermissions(AccountSasPermissions.Read); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // Create a SharedKeyCredential that we can use to sign the SAS token | ||||||||||||||||||||||||||||||||||||||||||||
| StorageSharedKeyCredential credential = new StorageSharedKeyCredential(StorageAccountName, StorageAccountKey); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // Build a SAS URI | ||||||||||||||||||||||||||||||||||||||||||||
| UriBuilder sasUri = new UriBuilder(StorageAccountBlobUri); | ||||||||||||||||||||||||||||||||||||||||||||
| sasUri.Query = sas.ToSasQueryParameters(credential).ToString(); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // Create a client that can authenticate with the SAS URI | ||||||||||||||||||||||||||||||||||||||||||||
| BlobServiceClient service = new BlobServiceClient(sasUri.Uri); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // Make a service request to verify we've successfully authenticated | ||||||||||||||||||||||||||||||||||||||||||||
| await service.GetPropertiesAsync(); | ||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| #### Connection string | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| The following code assumes you have acquired your connection string (you can do so from the Access Keys tab under Settings in your Portal Storage Account blade). It is recommended to store it in an environment variable. | ||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no need to go into details of the portal UI of how to acquire a connection string. Customer that have a connection string and looking to migrate already know how to get the connection string. They already have it and don't need to discover it again. Also, the |
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| [//]: # (Parsing the connection string in v11 vs v12.....) | ||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does this line do? Is this a link to external documents to be embedded? Or is this a TODO? |
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| Legacy (v11) | ||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider naming v11 legacy early in the document and there will be no need to note 'v11 (legacy)' all the time. The document's focus is to migrate from v11 to v12. That's the scope. |
||||||||||||||||||||||||||||||||||||||||||||
| ```c | ||||||||||||||||||||||||||||||||||||||||||||
| string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING"); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // Check whether the connection string can be parsed. | ||||||||||||||||||||||||||||||||||||||||||||
| CloudStorageAccount storageAccount; | ||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a missed documentation here. |
||||||||||||||||||||||||||||||||||||||||||||
| if (CloudStorageAccount.TryParse(storageConnectionString, out storageAccount)) | ||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||
| // If the connection string is valid, proceed with operations against Blob | ||||||||||||||||||||||||||||||||||||||||||||
| // storage here. | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||
| // Otherwise, user needs to define the environment variable. | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| v12 | ||||||||||||||||||||||||||||||||||||||||||||
| ```c | ||||||||||||||||||||||||||||||||||||||||||||
| string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING"); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // Create a client that can authenticate with a connection string | ||||||||||||||||||||||||||||||||||||||||||||
| BlobServiceClient service = new BlobServiceClient(connectionString); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // Make a service request to verify we've successfully authenticated | ||||||||||||||||||||||||||||||||||||||||||||
| await service.GetPropertiesAsync(); | ||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ### Shared Access Policies | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| TODO | ||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a miss... while I understand the time constraint, customers would likely have issues on the more advanced topics such as shared access policies and not how to create a blob client. |
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ### Client hierarchy | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| In the interest of simplifying the API surface we've made a three top level clients that can be used to interact with a majority of your resources: `BlobServiceClient`, `BlobContainerClient`, and `BlobClient`. | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| [//]: # (Blob Metadata, properties, and attributes...) | ||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this going to pull in some external articles? Given that changes associated with metadata/properties/attributes are breaking changes, this is the meat of the upgrade document. |
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ### Client constructors | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| | In v11 | In v12 | | ||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
| |-------|--------| | ||||||||||||||||||||||||||||||||||||||||||||
| | `CloudStorageAccount` | `BlobServiceClient` | | ||||||||||||||||||||||||||||||||||||||||||||
| | `CloudBlobContainer` | `BlobContainerClient` | | ||||||||||||||||||||||||||||||||||||||||||||
| | `CloudBlobClient` | `BlobClient` | | ||||||||||||||||||||||||||||||||||||||||||||
| | `CloudBlockBlob` | `BlockBlobClient` | | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ## Migration Samples | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ### Creating a Container | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| v11 | ||||||||||||||||||||||||||||||||||||||||||||
| ```c | ||||||||||||||||||||||||||||||||||||||||||||
| // Create the CloudBlobClient that represents the Blob storage endpoint for the storage account. | ||||||||||||||||||||||||||||||||||||||||||||
| CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient(); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| CloudBlobContainer cloudBlobContainer = | ||||||||||||||||||||||||||||||||||||||||||||
| cloudBlobClient.GetContainerReference("yourcontainer"); | ||||||||||||||||||||||||||||||||||||||||||||
| await cloudBlobContainer.CreateAsync(); | ||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| v12 | ||||||||||||||||||||||||||||||||||||||||||||
| ```c | ||||||||||||||||||||||||||||||||||||||||||||
| // Create a BlobServiceClient object which will be used to create a container client | ||||||||||||||||||||||||||||||||||||||||||||
| BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // Create a unique name for the container | ||||||||||||||||||||||||||||||||||||||||||||
| string containerName = "yourcontainer"; | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // Create the container and return a container client object | ||||||||||||||||||||||||||||||||||||||||||||
| BlobContainerClient containerClient = await blobServiceClient.CreateBlobContainerAsync(containerName); | ||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| Summary: In version 11, you would have to use the storage account endpoint to create the `CloudBlobClient`. Then you can get the container reference by calling the `GetContainerReference` method and create it by calling `CreateAsync()` on it. In version 12, you will use the `BlobServiceClient` object to then create `BlobContainerClient`. | ||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure what value this summary adds other than describing in sentences what the code above just did.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ### Uploading Blobs to a Container | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| v11 | ||||||||||||||||||||||||||||||||||||||||||||
| ```c | ||||||||||||||||||||||||||||||||||||||||||||
| // Assumes cloudBlobContainer already contains a reference to the container. | ||||||||||||||||||||||||||||||||||||||||||||
| // filename is the intended blob name as a string | ||||||||||||||||||||||||||||||||||||||||||||
| // localFilePath should be the path to the local file you want to upload | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // Get a reference to the blob address, then upload the file to the blob. | ||||||||||||||||||||||||||||||||||||||||||||
| CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(filename); | ||||||||||||||||||||||||||||||||||||||||||||
| await cloudBlockBlob.UploadFromFileAsync(localFilePath); | ||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| v12 | ||||||||||||||||||||||||||||||||||||||||||||
| ```c | ||||||||||||||||||||||||||||||||||||||||||||
| // Assumes containerClient already contains a reference to the container. | ||||||||||||||||||||||||||||||||||||||||||||
| // filename is the intended blob name as a string | ||||||||||||||||||||||||||||||||||||||||||||
| // localFilePath should be the path to the local file you want to upload | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // Get a reference to a blob | ||||||||||||||||||||||||||||||||||||||||||||
| BlobClient blobClient = containerClient.GetBlobClient(filename); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // Open the file and upload its data | ||||||||||||||||||||||||||||||||||||||||||||
| using FileStream uploadFileStream = File.OpenRead(localFilePath); | ||||||||||||||||||||||||||||||||||||||||||||
| await blobClient.UploadAsync(uploadFileStream, overwrite: true); | ||||||||||||||||||||||||||||||||||||||||||||
| uploadFileStream.Close(); | ||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| Summary: In v11, you would get the `CloudBlockBlob` reference by calling the `GetBlockBlobReference` method on the container name. Calling `UploadFromFileAsync` would then create the blob if it doesn't exist or overwrite the existing one. In v12, you will get the reference to the `BlobClient` object by calling the `GetBlobClient` method on the container and then upload the blob using the `UploadAsync` method. | ||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ### Downloading Blobs from a Container | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| Legacy (v11) | ||||||||||||||||||||||||||||||||||||||||||||
| ```c | ||||||||||||||||||||||||||||||||||||||||||||
| // Assumes you have already created a reference to the blob via blobClient | ||||||||||||||||||||||||||||||||||||||||||||
| // downloadFilePath should be the path to the intended file to download the blob to | ||||||||||||||||||||||||||||||||||||||||||||
| await cloudBlockBlob.DownloadToFileAsync(downloadFilePath, FileMode.Create); | ||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| v12 | ||||||||||||||||||||||||||||||||||||||||||||
| ```c | ||||||||||||||||||||||||||||||||||||||||||||
| // Assumes you have already created a reference to the blob via blobClient | ||||||||||||||||||||||||||||||||||||||||||||
| // downloadFilePath should be the path to the intended file to download the blob to | ||||||||||||||||||||||||||||||||||||||||||||
| BlobDownloadInfo download = await blobClient.DownloadAsync(); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| using (FileStream downloadFileStream = File.OpenWrite(downloadFilePath)) | ||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||
| await download.Content.CopyToAsync(downloadFileStream); | ||||||||||||||||||||||||||||||||||||||||||||
| downloadFileStream.Close(); | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+229
to
+233
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. using will invoke IDispose that will call .Close()
Suggested change
alternatively, |
||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ### Listing Blobs in a Container | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| Legacy (v11) | ||||||||||||||||||||||||||||||||||||||||||||
| ```c | ||||||||||||||||||||||||||||||||||||||||||||
| // List the blobs in the container. | ||||||||||||||||||||||||||||||||||||||||||||
| // Assumes a reference to the container via `cloudBlobContainer` | ||||||||||||||||||||||||||||||||||||||||||||
| BlobContinuationToken blobContinuationToken = null; | ||||||||||||||||||||||||||||||||||||||||||||
| do | ||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||
| var results = await cloudBlobContainer.ListBlobsSegmentedAsync(null, blobContinuationToken); | ||||||||||||||||||||||||||||||||||||||||||||
| // Get the value of the continuation token returned by the listing call. | ||||||||||||||||||||||||||||||||||||||||||||
| blobContinuationToken = results.ContinuationToken; | ||||||||||||||||||||||||||||||||||||||||||||
| foreach (IListBlobItem item in results.Results) | ||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||
| Console.WriteLine(item.Uri); | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| } while (blobContinuationToken != null); // Loop while the continuation token is not null. | ||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| v12 | ||||||||||||||||||||||||||||||||||||||||||||
| ```c | ||||||||||||||||||||||||||||||||||||||||||||
| // Get a reference to the container | ||||||||||||||||||||||||||||||||||||||||||||
| BlobContainerClient container = new BlobContainerClient(connectionString, containerName); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // List all blobs in the container | ||||||||||||||||||||||||||||||||||||||||||||
| await foreach (BlobItem blobItem in containerClient.GetBlobsAsync()) | ||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||
| Console.WriteLine("\t" + blobItem.Name); | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ### Other | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| ## Additional samples | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| More examples can be found at: | ||||||||||||||||||||||||||||||||||||||||||||
| - [Azure Storage samples using v12 .NET Client Libraries](https://docs.microsoft.com/en-us/azure/storage/common/storage-samples-dotnet?toc=/azure/storage/blobs/toc.json) | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+267
to
+272
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.