Dapr Binary Store .NET SDK
Store and retrieve binary files using the Dapr Binary Store .NET SDK
The Dapr Binary Store package lets .NET applications store, retrieve, stream, and delete binary files in a configured Dapr binary store component. It supports stream-based uploads and downloads for large files, as well as byte-array access for files that fit in memory. A source generator can also create a strongly typed client bound to a specific store.
To get started, follow the Dapr Binary Store how-to guide and refer to the client usage guidance for configuration, streaming, and error handling.
1 - How to: Manage binary files with the Dapr Binary Store .NET SDK
Learn how to store, retrieve, stream, and delete binary files using the Dapr Binary Store .NET SDK
Use the Dapr.BinaryStore package to store and retrieve files using a Dapr binary store component. The client streams file content in chunks, so you can work with large files without loading the entire file into memory. In this guide, you will:
- Register and configure
DaprBinaryStoreClient - Upload and download files using streams
- Choose between streaming and in-memory operations
- Bind a typed client to a store with the source generator
Prerequisites
.NET framework support
Be advised that .NET 8 and .NET 9 reach end of support in November 2026. Support for both will be dropped
in Dapr v1.20; only .NET 10 and .NET 11 will be supported through the end of 2027.Install the package in your project:
dotnet add package Dapr.BinaryStore
For local development, create a components directory in your application directory and save the following component as components\filestore.yaml:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: filestore
spec:
type: binarystore.in-memory
version: v1
metadata:
- name: maxSize
value: "4Mi"
- name: maxTotalSize
value: "512Mi"
This component stores files in the Dapr sidecar’s memory without requiring an external storage service. It allows files up to 4 MiB and a combined total of 512 MiB. Data is lost when the sidecar stops and is not shared across sidecars, so use it for local development and testing rather than durable storage.
The component’s metadata.name, filestore, is the store name supplied to the client methods or the [BinaryStore] attribute in the examples below.
Register the client
Register the client in dependency injection. By default, it reads the Dapr endpoint and API token from the environment or IConfiguration.
using Dapr.BinaryStore.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDaprBinaryStoreClient();
var app = builder.Build();
Start the application from its project directory with its Dapr sidecar, loading the in-memory component from components:
dapr run --app-id binary-store-example --resources-path .\components -- dotnet run
If you need to override the endpoint, configure the client builder:
builder.Services.AddDaprBinaryStoreClient((sp, clientBuilder) =>
{
clientBuilder.UseGrpcEndpoint("http://localhost:50001");
});
Upload and download a file
Resolve the registered client and pass the binary store component name, a file name, and a stream. The example uses the filestore component configured above. Place a report.pdf file no larger than 4 MiB in your application’s working directory before running the example. Add the following code after var app = builder.Build(); in Program.cs, with the using directives at the top of the file.
using Dapr.BinaryStore;
using Microsoft.Extensions.DependencyInjection;
var client = app.Services.GetRequiredService<DaprBinaryStoreClient>();
const string storeName = "filestore";
const string fileName = "uploads/report.pdf";
await using (var source = File.OpenRead("report.pdf"))
{
await client.SetBinaryFileAsync(storeName, fileName, source);
}
await using (var destination = File.Create("downloaded-report.pdf"))
{
await client.GetBinaryFileAsync(storeName, fileName, destination);
}
The example uploads report.pdf to the in-memory store as uploads/report.pdf and downloads it to downloaded-report.pdf. Run the remaining examples against the same sidecar to use the uploaded file before deleting it.
The Stream overload of SetBinaryFileAsync reads the input stream from its current position and sends it to the runtime in chunks. The default upload chunk size is 32 KiB; pass chunkSize to choose another positive size. Set overwrite: true to replace an existing file. By default, an upload fails if the file already exists.
File names can include nested paths such as uploads/report.pdf. Avoid a leading or trailing slash, empty path segments, . or .. segments, and the characters \, *, ?, [, ], and #; the Dapr runtime rejects these names.
Work with in-memory content
For content that already fits in memory, pass ReadOnlyMemory<byte> to upload or use GetBinaryFileBytesAsync to retrieve the complete file:
byte[] content = [0x01, 0x02, 0x03];
await client.SetBinaryFileAsync(storeName, "data.bin", content);
byte[] downloaded = await client.GetBinaryFileBytesAsync(storeName, "data.bin");
GetBinaryFileBytesAsync buffers the whole file in memory. Prefer GetBinaryFileAsync or GetBinaryFileChunksAsync for large files:
await using var chunkDestination = File.Create("downloaded-report-from-chunks.pdf");
await foreach (var chunk in client.GetBinaryFileChunksAsync(storeName, fileName))
{
await chunkDestination.WriteAsync(chunk);
}
Delete a file
await client.DeleteBinaryFileAsync(storeName, fileName);
Use a store-bound typed client
The package includes a source generator for a typed client that is bound to one component. Define a partial interface that extends IDaprBinaryStoreClient and use [BinaryStore] to specify the component name:
using Dapr.BinaryStore;
[BinaryStore("filestore")]
public partial interface IFileStore : IDaprBinaryStoreClient
{
}
Register the generated client after registering DaprBinaryStoreClient:
builder.Services
.AddDaprBinaryStoreClient()
.WithFileStore();
The generated WithFileStore method registers an implementation of IFileStore. Inject that interface where it is needed; its methods are the same as IDaprBinaryStoreClient but do not take a store name:
public sealed class ReportService(IFileStore fileStore)
{
public Task SaveAsync(string name, Stream content, CancellationToken cancellationToken) =>
fileStore.SetBinaryFileAsync(name, content, cancellationToken: cancellationToken);
}
2 - DaprBinaryStoreClient usage
Essential guidance for configuring and using DaprBinaryStoreClient
The operations on this page target SDK 1.19.0. Use that release or later with
Dapr runtime 1.19 or later.
Operation surface
| Operation | API |
|---|
| Upload | SetBinaryFileAsync with a Stream or ReadOnlyMemory<byte>, optionally overwriting an existing file. |
| Download | GetBinaryFileChunksAsync, GetBinaryFileAsync into a destination stream, or GetBinaryFileBytesAsync to buffer the complete file. |
| Delete | DeleteBinaryFileAsync. |
| Store-bound access | [BinaryStore] on a partial IDaprBinaryStoreClient interface and the generated With... DI registration. |
This SDK release does not expose list-files, file metadata, conditional/ETag writes, or range-read methods.
Binary store files are not state entries; state transactions and state query APIs do not apply to them.
Client lifetime
DaprBinaryStoreClient uses network resources and implements IDisposable. Reuse a long-lived client rather than creating one for each operation. The dependency injection registration uses ServiceLifetime.Singleton by default; use the optional lifetime argument to select another lifetime when needed.
using Dapr.BinaryStore.Extensions;
using Microsoft.Extensions.DependencyInjection;
builder.Services.AddDaprBinaryStoreClient(lifetime: ServiceLifetime.Singleton);
Client configuration
DaprBinaryStoreClientBuilder inherits the common Dapr client builder configuration. The client reads these values from environment variables or IConfiguration:
| Setting | Description |
|---|
DAPR_GRPC_ENDPOINT | gRPC endpoint address for the Dapr sidecar |
DAPR_HTTP_ENDPOINT | HTTP endpoint address for the Dapr sidecar |
DAPR_API_TOKEN | API token used to authenticate with the Dapr sidecar |
DAPR_GRPC_PORT | gRPC port used if DAPR_GRPC_ENDPOINT is not set |
DAPR_HTTP_PORT | HTTP port used if DAPR_HTTP_ENDPOINT is not set |
Values explicitly set on the builder take precedence over values from configuration:
using Dapr.BinaryStore.Extensions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
builder.Services.AddDaprBinaryStoreClient((sp, clientBuilder) =>
{
var configuration = sp.GetRequiredService<IConfiguration>();
var endpoint = configuration["DaprGrpcEndpoint"];
if (!string.IsNullOrEmpty(endpoint))
{
clientBuilder.UseGrpcEndpoint(endpoint);
}
});
The builder also supports UseHttpEndpoint, UseDaprApiToken, UseGrpcChannelOptions, and UseTimeout for applications that need to customize the common Dapr client settings.
Streaming and memory use
Use the Stream overload of SetBinaryFileAsync and GetBinaryFileAsync for large files. Uploads use a 32 KiB chunk size by default; specify chunkSize on upload to tune this, and ensure it is greater than zero. GetBinaryFileChunksAsync returns an asynchronous sequence of chunks chosen by the runtime.
The ReadOnlyMemory<byte> overload of SetBinaryFileAsync and GetBinaryFileBytesAsync are convenient for small files already held in memory. GetBinaryFileBytesAsync buffers the complete download in a byte array.
The caller owns the streams. Downloads write at the destination’s current position and do not rewind or
truncate it; uploads read at the source’s current position. Chunk enumeration is lazy, and runtime errors
can be thrown during enumeration. A failed download can leave partial bytes in the destination, which your
application must not treat as a complete file.
Cancellation
All asynchronous operations accept a CancellationToken. Pass the token through uploads, downloads, chunk enumeration, and deletes so the operation can be canceled when the caller no longer needs it:
await client.SetBinaryFileAsync(
storeName,
fileName,
source,
cancellationToken: cancellationToken);
When canceled, an OperationCanceledException is thrown. For chunk enumeration, pass the token to GetBinaryFileChunksAsync:
await foreach (var chunk in client.GetBinaryFileChunksAsync(
storeName,
fileName,
cancellationToken))
{
await ProcessChunkAsync(chunk);
}
Errors
The client throws DaprException when the Dapr runtime reports a failure. For example, a file that does not exist cannot be retrieved or deleted, and an upload without overwrite: true fails if a file with the same name already exists. Inspect InnerException for details from the runtime. Invalid client arguments, such as an empty store or file name or a non-positive upload chunk size, result in standard argument exceptions.