WriteableFileProviders.SharePoint
2027.1.1
dotnet add package WriteableFileProviders.SharePoint --version 2027.1.1
NuGet\Install-Package WriteableFileProviders.SharePoint -Version 2027.1.1
<PackageReference Include="WriteableFileProviders.SharePoint" Version="2027.1.1" />
<PackageVersion Include="WriteableFileProviders.SharePoint" Version="2027.1.1" />
<PackageReference Include="WriteableFileProviders.SharePoint" />
paket add WriteableFileProviders.SharePoint --version 2027.1.1
#r "nuget: WriteableFileProviders.SharePoint, 2027.1.1"
#:package WriteableFileProviders.SharePoint@2027.1.1
#addin nuget:?package=WriteableFileProviders.SharePoint&version=2027.1.1
#tool nuget:?package=WriteableFileProviders.SharePoint&version=2027.1.1
WriteableFileProviders.SharePoint
A SharePoint document library as an IWriteableFileProvider, through Microsoft Graph (Microsoft.Graph 6). Part of
WriteableFileProviders.
Install
dotnet add package WriteableFileProviders.SharePoint
Needs .NET 10, and is native AOT compatible: in an ASP.NET Core app, Microsoft Graph adds one harmless warning (Native AOT). Keep every WriteableFileProviders package in an app on the same major version.
Use
{
"Files": {
"Type": "WriteableSharePointFileProvider",
"SiteUrl": "https://contoso.sharepoint.com/sites/Finance",
"DocumentLibraryName": "Documents",
"TenantId": "<tenant id>",
"ClientId": "<app client id>",
"ClientSecret": "<from a secret store>",
"WorkFolderPath": "Apps/Reports"
}
}
services.AddWriteableFileProvider(configuration.GetSection("Files")); // then inject IWriteableFileProvider
Or pass a GraphServiceClient you build (managed identity, national clouds, custom handlers). The provider never
disposes it, and reads only the site, the library, the work folder and the root from the options. Downloads and uploads
go through it to hosts other than Graph's, so its authentication must send tokens to Graph only, as Azure Identity does:
var graph = new GraphServiceClient(new DefaultAzureCredential(), ["https://graph.microsoft.com/.default"]);
await using var files = new WriteableSharePointFileProvider(new SharePointFileProviderOptions { SiteUrl = siteUrl }, graph);
Configuration
| Option | Default | Meaning |
|---|---|---|
SiteUrl |
required | The site's absolute URL. |
DocumentLibraryName |
first library | The library as Graph names it: Documents for the default one (URL Shared Documents). |
TenantId, ClientId |
The app's Microsoft Entra tenant and client id; required with a secret or a certificate. With UseDefaultAzureCredential, ClientId picks a user-assigned managed identity. |
|
ClientSecret |
The app's client secret. A secret. | |
ClientCertificateBase64, ClientCertificatePassword |
The app's certificate with its private key, as a base64 .pfx, and its password. A secret. | |
UseDefaultAzureCredential |
false |
Sign in with DefaultAzureCredential: managed identity, workload identity, environment, developer sign-in. |
WorkFolderPath |
the library | A folder of the library that holds the root, created on the first write. Plain names (Team Files), never %20. |
RootDirectoryPath |
the work folder | The folder inside the work folder the provider is confined to. Plain names too. |
The root is WorkFolderPath then RootDirectoryPath. If the root starts with the work folder, that copy is dropped
(Apps/Reports twice is one Apps/Reports); a root that is only the start of it (Apps) is refused.
Authentication
The first configured wins: UseDefaultAzureCredential, a certificate, a client secret. With a certificate or a secret
the app signs in as itself: grant it the Graph application permission Sites.ReadWrite.All, or Sites.Selected with
write access to the site. Building the provider sends nothing; the site and library are looked up on the first call.
What's different
- Real folders, case ignored. Deletes go to the site's recycle bin.
- Names can't contain
:(Graph's path syntax). A%is literal:a%41namesa%41, notaA. - Writes go through a local temp file, then up in one request up to 4 MiB, or an upload session in 5 MiB fragments. A fragment that hits a server or network error is sent once more. A failed write leaves the old content.
- Conditions aren't atomic.
IfMatchandIfNotExistsare checked before the write and also sent to Graph. Appends rewrite the file withIf-Matchon the version read, and after a concurrent write read it again and append after it, up to five attempts in all. - Content type comes from the file name.
UpdateFileOptions.ContentTypeis ignored. - Lengths are real. A file whose size Graph doesn't report costs one extra ranged request to measure.
- Copies run on the server and are polled for about 10 minutes, then throw
IOException; the copy may still finish later. - Signed URLs are read only: Graph's download URL, which lives up to an hour. It's returned only with
AllowShorterValidityand a validity of an hour or more, withExpiresOnnull. Every other URL comes from the gateway. - Limits: Graph's own (fragments under 60 MiB, SharePoint's name and path lengths).
WatchthrowsNotSupportedException.
Learn more
- The guide: reading and writing, signed URLs, errors, providers compared.
- Moving from 2026.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- Azure.Identity (>= 1.21.0)
- Microsoft.Graph (>= 6.8.0)
- Microsoft.Graph.Core (>= 4.0.1)
- WriteableFileProviders.Common (>= 2027.1.1 && < 2028.0.0-alpha)
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 |
|---|---|---|
| 2027.1.1 | 73 | 10/13/2026 |
| 2027.1.1-rc.1 | 37 | 10/13/2026 |
| 2027.1.0 | 83 | 10/12/2026 |
| 2027.1.0-rc.1 | 52 | 10/12/2026 |
| 2027.0.0 | 294 | 10/11/2026 |
| 2027.0.0-rc.2 | 55 | 10/11/2026 |
What each release changed: https://github.com/serionist/WriteableFileProviders/blob/main/CHANGELOG.md. Moving from 2026.x: https://github.com/serionist/WriteableFileProviders/blob/main/docs/migration-2027.md