| title | Upload a blob with .NET |
|---|---|
| titleSuffix | Azure Storage |
| description | Learn how to upload a blob to your Azure Storage account using the .NET client library. |
| services | storage |
| author | stevenmatthew |
| ms.author | shaas |
| ms.date | 10/01/2025 |
| ms.service | azure-blob-storage |
| ms.topic | how-to |
| ms.devlang | csharp |
| ms.custom | devx-track-csharp, devguide-csharp, devx-track-dotnet |
[!INCLUDE storage-dev-guide-selector-upload]
This article shows how to upload a blob using the Azure Storage client library for .NET. You can upload data to a block blob from a file path, a stream, a binary object, or a text string. You can also open a blob stream and write to it, or upload large blobs in blocks.
[!INCLUDE storage-dev-guide-prereqs-dotnet]
[!INCLUDE storage-dev-guide-project-setup-dotnet]
The authorization mechanism must have the necessary permissions to upload a blob. For authorization with Microsoft Entra ID (recommended), you need Azure RBAC built-in role Storage Blob Data Contributor or higher. To learn more, see the authorization guidance for Put Blob (REST API) and Put Block (REST API).
You can use either of the following methods to upload data to a block blob:
When using these upload methods, the client library may call either Put Blob or a series of Put Block calls followed by Put Block List. This behavior depends on the overall size of the object and how the data transfer options are set.
To open a stream in Blob Storage and write to that stream, use either of the following methods:
Note
The Azure Storage client libraries don't support concurrent writes to the same blob. If your app requires multiple processes writing to the same blob, you should implement a strategy for concurrency control to provide a predictable experience. To learn more about concurrency strategies, see Manage concurrency in Blob Storage.
The following example uploads a block blob from a local file path:
:::code language="csharp" source="~/azure-storage-snippets/blobs/howto/dotnet/BlobDevGuideBlobs/UploadBlob.cs" id="Snippet_UploadFile":::
The following example uploads a block blob by creating a Stream object and uploading the stream.
:::code language="csharp" source="~/azure-storage-snippets/blobs/howto/dotnet/BlobDevGuideBlobs/UploadBlob.cs" id="Snippet_UploadStream":::
The following example uploads a block blob from a BinaryData object.
:::code language="csharp" source="~/azure-storage-snippets/blobs/howto/dotnet/BlobDevGuideBlobs/UploadBlob.cs" id="Snippet_UploadBinaryData":::
The following example uploads a block blob from a string:
:::code language="csharp" source="~/azure-storage-snippets/blobs/howto/dotnet/BlobDevGuideBlobs/UploadBlob.cs" id="Snippet_UploadString":::
You can open a stream in Blob Storage and write to it. The following example creates a zip file in Blob Storage and writes files to it. Instead of building a zip file in local memory, only one file at a time is in memory.
Warning
This approach can be very expensive if object replication policy is enabled because each write to the stream creates a new version of the zip file, and each version is copied to the destination account. The same is true if Azure Blob vaulted backup is enabled because vaulted backup uses object replication.
:::code language="csharp" source="~/azure-storage-snippets/blobs/howto/dotnet/BlobDevGuideBlobs/UploadBlob.cs" id="Snippet_UploadToStream":::
You can define client library configuration options when uploading a blob. These options can be tuned to improve performance, enhance reliability, and optimize costs. The following code examples show how to use BlobUploadOptions to define configuration options when calling an upload method.
You can configure the values in StorageTransferOptions to improve performance for data transfer operations. The following code example shows how to set values for StorageTransferOptions and include the options as part of a BlobUploadOptions instance. The values provided in this sample aren't intended to be a recommendation. To properly tune these values, you need to consider the specific needs of your app.
:::code language="csharp" source="~/azure-storage-snippets/blobs/howto/dotnet/BlobDevGuideBlobs/UploadBlob.cs" id="Snippet_UploadWithTransferOptions":::
To learn more about tuning data transfer options, see Performance tuning for uploads and downloads with .NET.
You can specify transfer validation options to help ensure that data is uploaded properly and hasn't been tampered with during transit. Transfer validation options can be defined at the client level using BlobClientOptions, which applies validation options to all methods called from a BlobClient instance.
You can also override transfer validation options at the method level using BlobUploadOptions. The following code example shows how to create a BlobUploadOptions object and specify an algorithm for generating a checksum. The checksum is then used by the service to verify data integrity of the uploaded content.
:::code language="csharp" source="~/azure-storage-snippets/blobs/howto/dotnet/BlobDevGuideBlobs/UploadBlob.cs" id="Snippet_UploadWithChecksum":::
The following table shows the available options for the checksum algorithm, as defined by StorageChecksumAlgorithm:
| Name | Value | Description |
|---|---|---|
| Auto | 0 | Recommended. Allows the library to choose an algorithm. Different library versions may choose different algorithms. |
| None | 1 | No selected algorithm. Don't calculate or request checksums. |
| MD5 | 2 | Standard MD5 hash algorithm. |
| StorageCrc64 | 3 | Azure Storage custom 64-bit CRC. |
Note
If the checksum specified in the request doesn't match the checksum calculated by the service, the upload operation fails. The operation is not retried when using a default retry policy. In .NET, a RequestFailedException is thrown with status code 400 and error code Md5Mismatch or Crc64Mismatch, depending on which algorithm is used.
Blob index tags categorize data in your storage account using key-value tag attributes. These tags are automatically indexed and exposed as a searchable multi-dimensional index to easily find data. You can add tags to a BlobUploadOptions instance, and pass that instance into the UploadAsync method.
The following example uploads a block blob with index tags:
:::code language="csharp" source="~/azure-storage-snippets/blobs/howto/dotnet/BlobDevGuideBlobs/UploadBlob.cs" id="Snippet_UploadBlobWithTags":::
You can set a blob's access tier on upload by using the BlobUploadOptions class. The following code example shows how to set the access tier when uploading a blob:
:::code language="csharp" source="~/azure-storage-snippets/blobs/howto/dotnet/BlobDevGuideBlobs/UploadBlob.cs" id="Snippet_UploadWithAccessTier":::
Setting the access tier is only allowed for block blobs. You can set the access tier for a block blob to Hot, Cool, Cold, or Archive. To set the access tier to Cold, you must use a minimum client library version of 12.15.0.
To learn more about access tiers, see Access tiers overview.
You can have greater control over how to divide uploads into blocks by manually staging individual blocks of data. When all of the blocks that make up a blob are staged, you can commit them to Blob Storage. You can use this approach to enhance performance by uploading blocks in parallel.
:::code language="csharp" source="~/azure-storage-snippets/blobs/howto/dotnet/BlobDevGuideBlobs/UploadBlob.cs" id="Snippet_UploadBlocks":::
To learn more about uploading blobs using the Azure Blob Storage client library for .NET, see the following resources.
The Azure SDK for .NET contains libraries that build on top of the Azure REST API, allowing you to interact with REST API operations through familiar .NET paradigms. The client library methods for uploading blobs use the following REST API operations:
- Performance tuning for uploads and downloads.
- Manage and find Azure Blob data with blob index tags
- Use blob index tags to manage and find data on Azure Blob Storage
[!INCLUDE storage-dev-guide-next-steps-dotnet]