Rystem.Content.Infrastructure.M365.Sharepoint 10.0.7

dotnet add package Rystem.Content.Infrastructure.M365.Sharepoint --version 10.0.7
                    
NuGet\Install-Package Rystem.Content.Infrastructure.M365.Sharepoint -Version 10.0.7
                    
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="Rystem.Content.Infrastructure.M365.Sharepoint" Version="10.0.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Rystem.Content.Infrastructure.M365.Sharepoint" Version="10.0.7" />
                    
Directory.Packages.props
<PackageReference Include="Rystem.Content.Infrastructure.M365.Sharepoint" />
                    
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 Rystem.Content.Infrastructure.M365.Sharepoint --version 10.0.7
                    
#r "nuget: Rystem.Content.Infrastructure.M365.Sharepoint, 10.0.7"
                    
#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 Rystem.Content.Infrastructure.M365.Sharepoint@10.0.7
                    
#: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=Rystem.Content.Infrastructure.M365.Sharepoint&version=10.0.7
                    
Install as a Cake Addin
#tool nuget:?package=Rystem.Content.Infrastructure.M365.Sharepoint&version=10.0.7
                    
Install as a Cake Tool

Rystem.Content.Infrastructure.M365.Sharepoint

This provider adds SharePoint Online support to the Content framework through Microsoft Graph.

It models one SharePoint document library as one IContentRepository registration.

Installation

dotnet add package Rystem.Content.Infrastructure.M365.Sharepoint

Authentication model

The current implementation uses Microsoft Graph with client credentials.

You need an app registration with application permissions such as:

  • Files.ReadWrite.All
  • or Sites.ReadWrite.All

And you need:

  • TenantId
  • ClientId
  • ClientSecret

Architecture

Async registration does real setup work:

  • it creates a GraphServiceClient
  • resolves the target site and document library ids
  • when a site-scoped library name is configured and the library is missing, it creates the document library

The 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.

Registration API

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

Mapping methods

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.

Example

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"
            }
        });
}

Provider behavior

  • UploadAsync writes file content through ItemWithPath(path).Content.PutAsync(...)
  • ExistAsync and GetPropertiesAsync query the file through Graph
  • ListAsync recursively enumerates folders
  • DeleteAsync returns true when the item does not exist

This provider is the most conceptually different from Blob and File Share because it does not map ContentRepositoryOptions to native SharePoint storage primitives.

Important caveats

Options are stored in DriveItem.Description

SetPropertiesAsync(...) serializes the whole ContentRepositoryOptions object into DriveItem.Description.

GetPropertiesAsync(...) reads that description back and deserializes it.

Practical consequence:

  • headers are not written as real SharePoint HTTP response headers
  • metadata is not mapped to list columns by this provider
  • tags are not native SharePoint tags

They round-trip because the provider stores its own JSON payload in the description field.

Site-name lookup is fuzzy

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.

Missing libraries can be created automatically

When a site is known and the requested document library name does not exist, the async setup path creates a document library for you.

Listing is recursive

Unlike the File Share provider, ListAsync(...) descends into child folders.

When to use this provider

Use it when you want:

  • SharePoint document libraries behind the shared content API
  • Microsoft 365 app-registration authentication
  • recursive listing over folder structures
  • convenient cross-provider migration targets

Be careful if you need native SharePoint field or header semantics, because this provider currently stores repository options in the item description instead.

Product 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. 
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
10.0.7 77 3/26/2026
10.0.6 182,046 3/3/2026
10.0.5 98 2/22/2026
10.0.4 106 2/9/2026
10.0.3 147,901 1/28/2026
10.0.1 209,075 11/12/2025
9.1.3 246 9/2/2025
9.1.2 764,493 5/29/2025
9.1.1 97,813 5/2/2025
9.0.32 186,718 4/15/2025
9.0.31 5,809 4/2/2025
9.0.30 88,837 3/26/2025
9.0.29 9,033 3/18/2025
9.0.28 242 3/17/2025
9.0.27 273 3/16/2025
9.0.26 289 3/13/2025
9.0.25 52,120 3/9/2025
9.0.21 339 3/6/2025
9.0.20 19,618 3/6/2025
9.0.19 345 3/6/2025
Loading failed