WopiHost.AzureStorageProvider 8.0.0

dotnet add package WopiHost.AzureStorageProvider --version 8.0.0
                    
NuGet\Install-Package WopiHost.AzureStorageProvider -Version 8.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="WopiHost.AzureStorageProvider" Version="8.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="WopiHost.AzureStorageProvider" Version="8.0.0" />
                    
Directory.Packages.props
<PackageReference Include="WopiHost.AzureStorageProvider" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add WopiHost.AzureStorageProvider --version 8.0.0
                    
#r "nuget: WopiHost.AzureStorageProvider, 8.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package WopiHost.AzureStorageProvider@8.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=WopiHost.AzureStorageProvider&version=8.0.0
                    
Install as a Cake Addin
#tool nuget:?package=WopiHost.AzureStorageProvider&version=8.0.0
                    
Install as a Cake Tool

WopiHost.AzureStorageProvider

NuGet NuGet

IWopiStorageProvider + IWopiWritableStorageProvider backed by Azure Blob Storage. WOPI files map directly to blobs; folders are virtual prefixes with a hidden zero-byte marker so empty folders remain addressable.

Suitable for production multi-instance deployments. Use with WopiHost.AzureLockProvider for distributed locking.

Install

dotnet add package WopiHost.AzureStorageProvider

Configure

Two authentication modes — connection string (Azurite, dev) and TokenCredential (managed identity, service principal):

// appsettings.json — connection string
"Wopi": {
  "StorageProvider": {
    "ConnectionString": "UseDevelopmentStorage=true",
    "ContainerName": "wopi-files"
  }
}
// appsettings.json — DefaultAzureCredential
"Wopi": {
  "StorageProvider": {
    "ServiceUri": "https://my-account.blob.core.windows.net",
    "ContainerName": "wopi-files"
  }
}

When ServiceUri is used the provider resolves a TokenCredential from DI; if none is registered, DefaultAzureCredential is created automatically. Register your own to override:

builder.Services.AddSingleton<TokenCredential>(new ManagedIdentityCredential(clientId));

The container is created on first use if it doesn't exist.

Register

builder.Services.AddAzureStorageProvider(builder.Configuration);
builder.Services.AddWopi(o =>
{
    o.ClientUrl = new Uri("https://your-office-online-server.com");
});

The runnable sample exposes a small Sample:StorageProvider discriminator (FileSystem / Azure) and dispatches to the chosen provider's typed extension — see sample/WopiHost/ServiceCollectionExtensions.cs.

How it maps to Blob Storage

WOPI concept Azure Blob equivalent
File content Blob bytes
IWopiFile.Length, LastWriteTimeUtc Blob ContentLength, LastModified
IWopiFile.Version Blob ETag (changes on every byte-level update)
IWopiFile.Owner Blob metadata key wopi_owner (empty string when unset)
IWopiFile.Checksum (SHA-256) Blob metadata key wopi_sha256 (lowercase hex), computed during upload
Folder Virtual blob-name prefix (/ delimiter) + zero-byte marker .wopi.folder for materialising empty folders
Identifier Hex-MD5 of the lowercased blob path (matches WopiHost.FileSystemProvider)

The provider scans the container at first access to populate the in-memory id-to-path map. Identifiers are stable across process restarts (deterministic from path) but not across renames — a rename re-points the existing id to the new path so the WOPI URL doesn't break mid-edit.

Caveats

  • Folder rename / delete-folder are O(N) over the children — plain Blob has no atomic prefix rename. If you do this often, consider switching to ADLS Gen2 (not currently supported, see issue #26) for atomic rename via the DFS endpoint.
  • Empty folders are materialised by writing a zero-byte .wopi.folder blob. Listings filter it out; deleting an empty folder removes the marker and drops the id.
  • SHA-256 is computed streaming on upload via HashingBlobWriteStream and stored as metadata. Pre-existing blobs that were not written through this provider will return null from Checksum until they are next written.
  • Owner is read from blob metadata; the provider doesn't set an owner on its own. Hosts that care about ownership should set wopi_owner themselves (e.g. via a custom write pipeline that enriches metadata after GetWriteStream).

Local development

The provider works against Azurite. The repo's Aspire AppHost runs Azurite as a container resource when AppHost:UseAzureStorage=true:

AppHost__UseAzureStorage=true dotnet run --project infra/WopiHost.AppHost

The Aspire orchestrator forwards the emulator connection string into WopiHost as ConnectionStrings:BlobStorage, which you can map into Wopi:StorageProvider:ConnectionString via standard configuration substitution.

License

See the repo README.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
8.0.0 197 5/14/2026
7.0.0 245 5/6/2026
6.0.0 142 5/3/2026