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

Install the package in your project:

dotnet add package Dapr.BinaryStore

Configure an in-memory binary store

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);
}
Last modified October 22, 2026: .NET review for 1.19 (69db68e36)