Robbiblubber.Util.FileStorageAdapters.SharePoint
1.0.2
dotnet add package Robbiblubber.Util.FileStorageAdapters.SharePoint --version 1.0.2
NuGet\Install-Package Robbiblubber.Util.FileStorageAdapters.SharePoint -Version 1.0.2
<PackageReference Include="Robbiblubber.Util.FileStorageAdapters.SharePoint" Version="1.0.2" />
<PackageVersion Include="Robbiblubber.Util.FileStorageAdapters.SharePoint" Version="1.0.2" />
<PackageReference Include="Robbiblubber.Util.FileStorageAdapters.SharePoint" />
paket add Robbiblubber.Util.FileStorageAdapters.SharePoint --version 1.0.2
#r "nuget: Robbiblubber.Util.FileStorageAdapters.SharePoint, 1.0.2"
#:package Robbiblubber.Util.FileStorageAdapters.SharePoint@1.0.2
#addin nuget:?package=Robbiblubber.Util.FileStorageAdapters.SharePoint&version=1.0.2
#tool nuget:?package=Robbiblubber.Util.FileStorageAdapters.SharePoint&version=1.0.2
robbiblubber.org SharePoint Adapter Library
The robbiblubber.org SharePoint Adapter Library provides access to SharePoint
Online document libraries through the common API defined by the
FileStorageAdapters Library. Applications can work with remote files and
directories through IFile, IDirectory, and IElement without depending
directly on Microsoft Graph for file operations.
The adapter uses Microsoft Graph and Azure Identity for remote access and authentication. Each adapter instance exposes one document library as its logical file-system root.
The repository can be found at https://bitbucket.org/robbiblubber/robbiblubber.util.filestorageadapters.net/. API documentation is available from https://robbiblubber.lima-city.org/. For general information see http://robbiblubber.org/.
The robbiblubber.org SharePoint Adapter Library is provided under the MIT license and may be used without restrictions under the conditions of this license agreement.
Opening a Directory
SharePointAdapter implements IAdapter and represents a connection to a
selected document library. A directory can be opened through an adapter
instance:
using Robbiblubber.Util.FileStorageAdapters;
using Robbiblubber.Util.FileStorageAdapters.SharePoint;
SharePointTarget target = SharePointTarget.FromSiteUrl(
"https://tenant.sharepoint.com/sites/project",
libraryName: "Documents");
using SharePointAdapter adapter = SharePointAdapter.CreateInteractive(
target,
tenantId: "TENANT-ID",
clientId: "APPLICATION-ID");
IDirectory directory = adapter.OpenDirectory("/reports");
The path must identify an existing directory. The returned IDirectory
instance is the initial context for navigation and file operations. Keep the
adapter alive while using its files, directories, and streams, and dispose it
when those operations are complete.
SharePointTarget supports selection by site URL, Graph site ID, SharePoint
host name and server-relative site path, or Graph drive ID:
SharePointTarget byUrl = SharePointTarget.FromSiteUrl(
"https://tenant.sharepoint.com/sites/project", "Documents");
SharePointTarget bySite = SharePointTarget.FromSiteId("SITE-ID", "Documents");
SharePointTarget byPath = SharePointTarget.FromSitePath(
"tenant.sharepoint.com", "/sites/project", "Documents");
SharePointTarget byDrive = SharePointTarget.FromDriveId("DRIVE-ID");
For site-based selection, omitting the library name selects the site's default document library. A drive ID identifies the document library directly.
Authentication
SharePointAuthenticationOptions supports interactive browser, device-code,
client-secret, client-certificate, managed-identity, and
DefaultAzureCredential authentication:
SharePointAuthenticationOptions authentication = new()
{
Mode = SharePointAuthenticationMode.InteractiveBrowser,
TenantId = "TENANT-ID",
ClientId = "APPLICATION-ID",
RedirectUri = "http://localhost"
};
using SharePointAdapter adapter = new(target, authentication);
IDirectory directory = adapter.OpenDirectory("/");
Convenience factories are available as CreateInteractive, CreateDeviceCode,
CreateClientSecret, CreateClientCertificate, CreateManagedIdentity, and
CreateDefaultCredential. Static Open overloads accept authentication
options, an Azure Core TokenCredential, or an existing GraphServiceClient.
Use an explicit adapter instance when you need to control its disposal with
using. The following alternatives reuse target from the opening example.
An externally created credential can be supplied for other authentication flows or application-specific credential handling:
using Azure.Core;
using Azure.Identity;
TokenCredential credential = new DefaultAzureCredential();
using SharePointAdapter adapter = new(credential, target);
An existing GraphServiceClient can also be supplied to reuse authentication,
HTTP configuration, or middleware. Supplied clients and credentials remain
owned by the caller unless ownsGraph or ownsCredential is set to true.
Authentication settings expose scopes and an optional authority host.
SharePointAdapterOptions.GraphBaseUrl configures the Graph endpoint. The
default scope is https://graph.microsoft.com/.default; custom cloud settings
must use matching authority, endpoint, and scope values.
The configured identity must have access to the selected document library and permission to perform the requested operations. Authentication alone does not grant access to SharePoint content.
Supported Operations
The adapter supports the operations provided by the FileStorageAdapters base library, including:
- listing and asynchronously enumerating files and directories;
- resolving elements by relative or absolute path;
- reading files as streams;
- creating and deleting files and directories;
- copying and moving files and directory trees;
- uploading local files and directories through the common adapter API;
- downloading files and directory trees; and
- filtering directory contents with file-system-style expressions.
Files may be copied or moved between SharePoint and any other
FileStorageAdapters implementation. Cross-adapter file transfers use streams;
directory transfers are performed recursively. Cross-adapter moves copy before
deleting the source and are not atomic. Directory copies with overwrite: true
merge into an existing destination directory of the same name and retain
unrelated destination files.
Paths and Remote Behavior
The selected document library is exposed as /. Both / and \ are accepted
as logical path separators, and . and .. are resolved within that library.
An initial directory does not restrict navigation back to the library root;
navigation cannot escape into another document library or site.
Element paths are logical library-relative paths rather than local paths or SharePoint web URLs. The adapter resolves paths to Graph item IDs for operations such as reading file content.
File and directory operations require network access and remain subject to
SharePoint access rules and service restrictions. OpenDirectory is
synchronous and may perform network requests. Asynchronous enumeration loads
the directory listing before yielding its elements.
Uploads
The adapter uses simple uploads for files up to 250,000,000 bytes by default.
Larger files use a Graph upload session with sequential fragments and retries
for transient upload failures. Transfer settings are available through
SharePointAdapterOptions.
The default fragment size is 10 times 320 KiB. Configured fragment sizes must be multiples of 320 KiB and smaller than 60 MiB. Non-seekable input streams are copied to a temporary seekable file before uploading, so sufficient temporary disk space is required. Seekable streams are read from their current position. Cancellation does not undo transfers that have already completed.
Metadata
Elements expose their logical path and the creation time, modification time, size, and ETag supplied by Microsoft Graph. Directory sizes use the size reported by Graph rather than a recursive client-side calculation.
Files expose their reported content type when available. Directory content
types are returned as null. Metadata reflects the information obtained when
the element was retrieved; it is not a live subscription to remote changes.
Example
SharePointTarget target = SharePointTarget.FromSiteUrl(
"https://tenant.sharepoint.com/sites/project",
libraryName: "Documents");
using SharePointAdapter adapter = SharePointAdapter.CreateInteractive(
target,
tenantId: "TENANT-ID",
clientId: "APPLICATION-ID");
IDirectory directory = adapter.OpenDirectory("/");
IFile source = await directory.GetFileAsync("input/report.txt");
await using Stream content = await source.ReadAsync();
IDirectory output = await directory.CreateDirectoryAsync("output");
IFile copy = await output.CreateFileAsync(
"report.txt",
content,
overwrite: true);
Console.WriteLine(copy.Path);
Streams returned by ReadAsync are owned by the caller and must be disposed.
Streams supplied to CreateFileAsync remain owned by the caller and are not
disposed by the adapter.
Concurrent operations and disposal
Adapter requests may execute concurrently. DisposeAsync() stops admission of
new operations and waits for admitted operations, including all download bytes,
pages and upload fragments, before disposing owned resources. Dispose() waits
synchronously for that same result. Copies and moves may contain several such
operations and are not transactions.
ReadAsync() downloads the whole file into a local temporary snapshot before
returning. Snapshots are read-only and seekable, remain usable after adapter
disposal and must be disposed by the caller to remove their temporary storage.
One stream supports one consumer. Budget local temporary space for every open
snapshot and allow for the full download latency before ReadAsync() completes.
Small uploads send @microsoft.graph.conflictBehavior=fail when overwrite is
false. Upload sessions specify the corresponding conflict behavior in their
request. Concurrent folder creation recovers a nameAlreadyExists conflict only
when rereading the path confirms a directory.
An externally supplied Graph client must already have the requested GraphBaseUrl. The adapter does not reconfigure shared clients. Direct calls through GraphClient are outside the adapter's lifetime tracking; callers must coordinate those calls and must not mutate or dispose the client while adapter operations are active. Do not await adapter disposal from an active source-stream or authentication callback: the enclosing operation must finish before disposal can complete.
Implementation and test status: see THREAD-SAFETY-PLAN.md in the source archive.
| Product | Versions 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 was computed. 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. |
-
net10.0
- Azure.Identity (>= 1.21.0)
- Microsoft.Graph (>= 6.8.0)
- Robbiblubber.Util.FileStorageAdapters (>= 1.0.2)
-
net8.0
- Azure.Identity (>= 1.21.0)
- Microsoft.Graph (>= 6.8.0)
- Robbiblubber.Util.FileStorageAdapters (>= 1.0.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.