Fixing "Identifier Malformed" and "Resource Not Found" Errors When Uploading to SharePoint with C# and MS Graph SDK
Uploading files to SharePoint using Microsoft Graph in C# can be tricky, especially when dealing with site paths and drives. Let’s break down why you’re seeing errors like Provided identifier is malformed
or Resource not found for the segment 'Documents'
and how to resolve them.
Understanding the Problem
Your code tries to access a SharePoint site and its drive like this:
var driveItem = await client.Sites["acme.sharepoint.com/sites/ndexport1"].Drive.GetAsync();
This fails because the site identifier format is incorrect. Similarly, trying to include Documents
in the path (e.g., .../ndexport1/Documents/
) throws a Resource not found
error because Documents
is a drive, not a site segment.
Step 1: Correct the Site Identifier
The Microsoft Graph API expects site identifiers in a specific format:
// Use colon (:) and slash (/) to specify the server-relative path var site = await client.Sites["acme.sharepoint.com:/sites/ndexport1"].GetAsync();
Why This Works: The
:/
syntax tells Graph to treat the path as relative to the SharePoint tenant root.
Step 2: Access the Drive (Document Library)
Once you have the correct site reference, retrieve its default drive (e.g., the Documents
library):
var drive = await client.Sites["acme.sharepoint.com:/sites/ndexport1"].Drive.GetAsync();
No Need for
/Documents
: TheDrive
property points to the default document library.
Step 3: Upload Files to the Drive
Use the drive ID to upload files:
// Example: Upload to the root folder of the drive var uploadSession = await client.Drives[drive.Id].Root .ItemWithPath("myfile.txt") .CreateUploadSession() .Request() .PostAsync();
Why Your Original Code Failed
Malformed Identifier:
❌
client.Sites["acme.sharepoint.com/sites/ndexport1"]
✅
client.Sites["acme.sharepoint.com:/sites/ndexport1"]
Missing
:
and/
caused the malformed error.
Invalid Path for Documents:
The
Documents
library is a drive, not part of the site path.Use
Drive
after resolving the site correctly.
Full Working Example
using Microsoft.Graph; using Azure.Identity; var scopes = new[] { "https://graph.microsoft.com/.default" }; var options = new ClientSecretCredentialOptions { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud }; var authProvider = new ClientSecretCredential(_tenantId, _clientId, _clientSecret, options); var client = new GraphServiceClient(authProvider, scopes); // 1. Get the site with the correct identifier var site = await client.Sites["acme.sharepoint.com:/sites/ndexport1"].GetAsync(); // 2. Get the drive (document library) var drive = await client.Sites[site.Id].Drive.GetAsync(); // 3. Upload a file using var fileStream = File.OpenRead("path/to/yourfile.txt"); var uploadSession = await client.Drives[drive.Id].Root .ItemWithPath("yourfile.txt") .CreateUploadSession() .Request() .PostAsync(); var uploadTask = new LargeFileUploadTask<DriveItem>(uploadSession, fileStream); var result = await uploadTask.UploadAsync(); if (result.UploadSucceeded) Console.WriteLine("File uploaded!");
Alternative: Use Site ID or Drive ID
If you know the Site ID or Drive ID, use them directly:
// By Site ID var site = await client.Sites["{SITE_ID}"].GetAsync(); // By Drive ID var drive = await client.Drives["{DRIVE_ID}"].GetAsync();
Find these IDs in the SharePoint URL or via the Graph API.
Key Takeaways
Use
:/
in site identifiers for server-relative paths.Access drives through the
Drive
property of a site.Avoid adding
Documents
to the site path—it’s a drive, not a segment.
With these fixes, you’ll bypass malformed identifier errors and upload files successfully! 🚀
Post a Comment