Update fields for a file in Sharepoint document library with Graph SDK C#

305 Views Asked by At

I'm using the C# SDK for the Graph API in my C# application to work with Sharepoint. This works fine for filling up a List with data with custom fields and uploading files in a document library also works fine. However, updating custom fields for a file in a document library doesn't seem to work.

I'm using .NET 6 and the Microsoft.Graph NuGet package (5.27.0)

I use the following request to upload the file:

 var newFile = graphClient
        .Drives[await GetDriveId(docLibraryName, link)]
        .Root
        .ItemWithPath(fileName)
        .Content
        .PutAsync(fileStream);

GetDriveId() will use the Site Id to fetch the drive id of the document library

I use the id from that upload to get the id of the ListItem:

var listItem = await graphClient
    .Drives[await GetDriveId(docLibraryName, link)]
    .Items[newFile.Id]
    .ListItem
    .GetAsync((requestConfiguration) =>
    {
        requestConfiguration.QueryParameters.Select = new string[] { "Id" };
    });

After that I use the id to update the fields of the ListItem:

var itemToAdd = new Microsoft.Graph.Models.ListItem
{
    Fields = new Microsoft.Graph.Models.FieldValueSet
    {
        AdditionalData = new Dictionary<string, object>()
        {
            { SpoDocument.Owner, document.Owner },
            { SpoDocument.Datum, document.Datum },
            { SpoDocument.Ref1, document.Ref1 },
            { SpoDocument.Ref2, document.Ref2 },
            { SpoDocument.Ref3, document.Ref3 },
            { SpoDocument.Ref4, document.Ref4 },
            { SpoDocument.MailTo, document.MailTo },
            { SpoDocument.MailBcc, document.MailBCC },
            { SpoDocument.MailCc, document.MailCC },
            { SpoDocument.BodyMail, document.BodyMail },
            { SpoDocument.ContactPersonen, document.Contactpersonen },
            { SpoDocument.Activiteit, document.Activiteit },
            { SpoDocument.VerkoopCategorie, document.VerkoopCategorie },
            { SpoDocument.InkoopCategorie, document.InkoopCategorie },
        }
    }
};

 await graphClient
 .Drives[await GetDriveId(docLibraryName, link)]
 .List
 .Items[listItem.Id]
 .PatchAsync(itemToAdd)

This however returns an exception with "General exception while processing". The SpoDocumentClass just contains constant strings with the available columns in the document library, here you can see some columns

If afterwards I try to fetch those custom fields using the following function they don't appear in the list of fields which makes me think they are not available somehow? As can be seen here

var test = await graphClient
    .Drives[await GetDriveId(docLibraryName, link)]
    .Items[fileId]
    .ListItem
    .GetAsync((requestConfiguration) =>
    {
        requestConfiguration.QueryParameters.Expand = new string[] { "Fields" };
    });

If however I fetch the list of columns of the document library, they do appear in there as can be seen here

var test2 = await graphClient
    .Drives[await GetDriveId(docLibraryName, link)]
    .List.GetAsync((requestConfiguration) =>
    {
        requestConfiguration.QueryParameters.Expand = new string[] { "Columns" };
    });

I would like to be able to update the fields of my document in the document library using the Graph SDK

1

There are 1 best solutions below

1
On

You could use following code to Update fields

using System;
using System.Collections.Generic;
using Microsoft.Graph;
using Microsoft.Identity.Client;

class Program
{
    static async System.Threading.Tasks.Task Main(string[] args)
    {
        string clientId = "YourClientId";
        string clientSecret = "YourClientSecret";
        string tenantId = "YourTenantId";
        string siteId = "YourSiteId";
        string documentLibraryId = "YourDocumentLibraryId";
        string fileId = "YourFileId";

        IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
            .Create(clientId)
            .WithClientSecret(clientSecret)
            .WithAuthority(new Uri($"https://login.microsoftonline.com/{tenantId}"))
            .Build();

        var authProvider = new ClientCredentialProvider(confidentialClientApplication, "https://graph.microsoft.com/.default");

        var graphServiceClient = new GraphServiceClient(authProvider);

        // Define the properties you want to update
        var updatedProperties = new Dictionary<string, object>
        {
            { "Title", "New Title" },
            { "Description", "New Description" },
            // Add other properties as needed
        };

        // Update file properties
        var updatedDriveItem = await graphServiceClient
            .Sites[siteId]
            .Drives[documentLibraryId]
            .Items[fileId]
            .Request()
            .UpdateAsync(new DriveItem
            {
                AdditionalData = updatedProperties,
            });

        Console.WriteLine($"Updated file properties. New title: {updatedDriveItem.Name}");
    }
}