![]() |
VOOZH | about |
dotnet add package Rystem.Content.Infrastructure.M365.Sharepoint --version 10.0.8
NuGet\Install-Package Rystem.Content.Infrastructure.M365.Sharepoint -Version 10.0.8
<PackageReference Include="Rystem.Content.Infrastructure.M365.Sharepoint" Version="10.0.8" />
<PackageVersion Include="Rystem.Content.Infrastructure.M365.Sharepoint" Version="10.0.8" />Directory.Packages.props
<PackageReference Include="Rystem.Content.Infrastructure.M365.Sharepoint" />Project file
paket add Rystem.Content.Infrastructure.M365.Sharepoint --version 10.0.8
#r "nuget: Rystem.Content.Infrastructure.M365.Sharepoint, 10.0.8"
#:package Rystem.Content.Infrastructure.M365.Sharepoint@10.0.8
#addin nuget:?package=Rystem.Content.Infrastructure.M365.Sharepoint&version=10.0.8Install as a Cake Addin
#tool nuget:?package=Rystem.Content.Infrastructure.M365.Sharepoint&version=10.0.8Install as a Cake Tool
This provider adds SharePoint Online support to the Content framework through Microsoft Graph.
It models one SharePoint document library as one IContentRepository registration.
dotnet add package Rystem.Content.Infrastructure.M365.Sharepoint
The current implementation uses Microsoft Graph with client credentials.
You need an app registration with application permissions such as:
Files.ReadWrite.AllSites.ReadWrite.AllAnd you need:
TenantIdClientIdClientSecretAsync registration does real setup work:
GraphServiceClientThe registration extensions live in BuilderExtensions/ContentRepositoryBuilderExtensions.cs, the mapping rules in Options/SharepointConnectionSettings.cs, and the runtime behavior in SharepointRepository/SharepointRepository.cs plus SharepointServiceClient/SharepointServiceClientFactory.cs.
| Method | Default lifetime | Notes |
|---|---|---|
WithSharepointIntegrationAsync(options, name, serviceLifetime) |
Transient |
preferred path because setup is async |
WithSharepointIntegration(options, name, serviceLifetime) |
Transient |
sync wrapper over the async implementation |
Call exactly one of these on SharepointConnectionSettings:
| Method | Meaning |
|---|---|
MapWithSiteIdAndDocumentLibraryId(siteId, documentLibraryId) |
use exact ids |
MapWithSiteIdAndDocumentLibraryName(siteId, documentLibraryName) |
site id plus library name |
MapWithSiteNameAndDocumentLibraryName(siteName, documentLibraryName) |
find the site by name, then find or create the library |
MapWithRootSiteAndDocumentLibraryName(documentLibraryName) |
use the root site and a library name |
MapOnlyDocumentLibraryId(documentLibraryId) |
search by library id only |
MapOnlyDocumentLibraryName(documentLibraryName) |
search by library name only |
If your tenant has ambiguous site names, prefer the id-based methods.
This matches src/Content/Rystem.Content.Tests/Rystem.Content.UnitTest/Startup.cs.
var repositories = builder.Services.AddContentRepository();
await repositories.WithSharepointIntegrationAsync(options =>
{
options.TenantId = builder.Configuration["Sharepoint:TenantId"];
options.ClientId = builder.Configuration["Sharepoint:ClientId"];
options.ClientSecret = builder.Configuration["Sharepoint:ClientSecret"];
options.MapWithSiteNameAndDocumentLibraryName(
builder.Configuration["Sharepoint:SiteName"]!,
builder.Configuration["Sharepoint:DocumentLibraryName"]!);
}, "sharepoint");
Resolve and use it:
public sealed class SharepointContentService
{
private readonly IContentRepository _repository;
public SharepointContentService(IFactory<IContentRepository> factory)
=> _repository = factory.Create("sharepoint");
public ValueTask<bool> UploadAsync(string path, byte[] data)
=> _repository.UploadAsync(path, data, new ContentRepositoryOptions
{
HttpHeaders = new ContentRepositoryHttpHeaders
{
ContentType = "application/pdf"
},
Metadata = new Dictionary<string, string>
{
["department"] = "legal"
},
Tags = new Dictionary<string, string>
{
["version"] = "1"
}
});
}
UploadAsync writes file content through ItemWithPath(path).Content.PutAsync(...)ExistAsync and GetPropertiesAsync query the file through GraphListAsync recursively enumerates foldersDeleteAsync returns true when the item does not existThis provider is the most conceptually different from Blob and File Share because it does not map ContentRepositoryOptions to native SharePoint storage primitives.
DriveItem.DescriptionSetPropertiesAsync(...) serializes the whole ContentRepositoryOptions object into DriveItem.Description.
GetPropertiesAsync(...) reads that description back and deserializes it.
Practical consequence:
They round-trip because the provider stores its own JSON payload in the description field.
When you use MapWithSiteNameAndDocumentLibraryName(...), the provider searches Graph sites and takes the first match.
If you have multiple similarly named sites, use the id-based mapping methods instead.
When a site is known and the requested document library name does not exist, the async setup path creates a document library for you.
Unlike the File Share provider, ListAsync(...) descends into child folders.
Use it when you want:
Be careful if you need native SharePoint field or header semantics, because this provider currently stores repository options in the item description instead.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.0.8 | 5,498 | 5/13/2026 |
| 10.0.7 | 128 | 3/26/2026 |
| 10.0.6 | 433,511 | 3/3/2026 |
| 10.0.5 | 126 | 2/22/2026 |
| 10.0.4 | 133 | 2/9/2026 |
| 10.0.3 | 147,930 | 1/28/2026 |
| 10.0.1 | 209,101 | 11/12/2025 |
| 9.1.3 | 275 | 9/2/2025 |
| 9.1.2 | 764,515 | 5/29/2025 |
| 9.1.1 | 97,835 | 5/2/2025 |
| 9.0.32 | 186,738 | 4/15/2025 |
| 9.0.31 | 5,832 | 4/2/2025 |
| 9.0.30 | 88,862 | 3/26/2025 |
| 9.0.29 | 9,057 | 3/18/2025 |
| 9.0.28 | 265 | 3/17/2025 |
| 9.0.27 | 297 | 3/16/2025 |
| 9.0.26 | 312 | 3/13/2025 |
| 9.0.25 | 52,142 | 3/9/2025 |
| 9.0.21 | 359 | 3/6/2025 |
| 9.0.20 | 19,638 | 3/6/2025 |