Accessing SharePoint Data From Azure Function Via Graph API

In this article, we will learn step by step guide on how to access SharePoint data from the Azure function via Graph API.

Why this use case-  There can be various reasons to create Azure function and access SharePoint Data from it, but in this particular case, the Azure function was supposed to call from an on-premises application which was holding clients in a custom database and they wanted to sync this clients information to SP online in the list for displaying it in PowerApps. So the prime responsibility of this Azure function is where it will receive a JSON payload holding the client's information and AzFunc would check if the client already exists in the SP list then update it or else create a new item in the Client list.

Create a new Azure AD App Registration 

This is a common step when we need to access Graph API from an external system, I am going to skip this in this article.

Depending on what kind of resources you are going to access in your Azure function, you can choose API permission and also choose if it is delegated or application permission. In this particular case, we will choose application permission and Site.ReadWrite.All

Also, provide Admin consent as we are using application permissions and would be accessing SharePoint Data directly with any user intervention.

In this step, you have to note down ClientId, Client Secret, and Tenant ID which will be used later.

Create Azure Function Project

For the sake of this article, we are going to create C#.net-based Azure function but you can choose to do it in other supported languages also...

Open Visual Studio (not code) - Create a new Project and Choose Azure Functions.

Note - Assuming, you have Azure Function development template/tool is installed, if not refer to this link

Choose Project name and solution path and on click of Next it will ask you trigger type and .NET version(as in the below screenshot)

Choose Azure Function v3(latest as on article date) and HTTP trigger

It would create the project and you should see something like below

You can rename the function name and File name according to your preference.

As the focus of this article is to get/access data from SharePoint. Let us start creating files/functions etc required to authenticate and methods that will be used later for your business logic.

Install Graph SDK NuGet Packages

We will be using the NuGet Graph SDK package which will have methods/functions and class interact with any Graph endpoint and resources.

Go to Tools-> NuGet Package Manager - Manage NuGet Packages for Solutions

Click on Browse and search for Microsoft.Graph and install below libraries

Microsoft.Graph and a then similar way for Microsoft.Graph.Auth,  Microsoft.Identity.Client

Below NuGet Package would be required for this sample

Once you have all of them installed..it is time to start writing modifying code for required

Create a local configuration file, modify local.settings.json

{
    "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "clientid": "f123452-1211-`123-8121-11231238",
    "tenantid": "ce1232130-b1235-41237-81235-7123123129",
    "clientSecret": "4123123123213123123adsfsadfsadf",
    "siteId": "yourtenant.sharepoint.com,dd1231234-3121-4124-9e38-a0123123a90,e7312323-011235c-4a73-b833-c8asdjk12d2dd",
    "clientsListID": "f111235c-c111-4121-91233-cadsf123123sa"
  }
}

Client ID - This is your App Registration Client Id

Client Secret - This is a client Secret created in App Registration tep

Tenant ID - This is your tenant ID, you can get this from Azure Active Directory

List-ID - ID of list from where we wanted to read data

Site ID - This is the Site ID to which you have to connect where the list is created but it is a little tricker, you can get this from Graph Explorer.

Go to Graph Explorer and hit the below endpoint and you will get Site ID in the above format...(screenshot below for reference)

https://graph.microsoft.com/v1.0/sites?search=NameofYoursite

Modify code to Read data from SP list and then write to the console

In an ideal scenario, you can process this list data, do some operations and return the data in JSON format but for simplicity here we are just writing data to console and returning the default message that the HTTP Trigger function  has been executed successfully

Below is high-level steps that are done in code

  • Read Environment Variable to get configuration values like client Id, secret, tenant id, list id, and site id. This would be required when making an actual graph API call to get data from a list.
  • Create a GraphServiceClient object using client id, tenant id, and secret to connect to Graph Service.
  • Call GraphServiceClient method to request items from the SP list
  • Loop through the items returned and write to console.

You can replace the below file as it is in your code

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Graph;
using Microsoft.Identity.Client;
using Microsoft.Graph.Auth;
using System.Collections.Generic;

namespace AzFuncClientsToSPList
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            ConfigurationsValues configValues = readEnviornmentVariable();
            GraphServiceClient _graphServiceClient = getGraphClient(configValues);
            var queryOptions = new List<QueryOption>()
                            {
                                new QueryOption("expand", "fields(select=ID,Title,Name)")
                            };
            IListItemsCollectionPage _listItems;
            try
            {

                _listItems = await _graphServiceClient.Sites[configValues.SiteId].Lists[configValues.clientsListID].Items
                                 .Request(queryOptions)
                                 .GetAsync();
            }
            catch (Exception ex)
            {
                throw ex;
            }
          
            foreach (var item in _listItems.CurrentPage)
            {
                Console.WriteLine("-----------------------------Item ID " + item.Id+ "---------------------");
                Console.WriteLine("Title---" + item.Fields.AdditionalData["Title"]);
                Console.WriteLine("Name---" + item.Fields.AdditionalData["Name"]);

            }
            return new OkObjectResult("This HTTP triggered function executed successfully");
        }

        public static ConfigurationsValues readEnviornmentVariable()
        {
            ConfigurationsValues configValues = new ConfigurationsValues();

            configValues.Tenantid = System.Environment.GetEnvironmentVariable("tenantid", EnvironmentVariableTarget.Process);
            configValues.Clientid = System.Environment.GetEnvironmentVariable("clientid", EnvironmentVariableTarget.Process);
            configValues.ClientSecret = System.Environment.GetEnvironmentVariable("clientsecret", EnvironmentVariableTarget.Process);
            configValues.SiteId = System.Environment.GetEnvironmentVariable("siteId", EnvironmentVariableTarget.Process);
            configValues.clientsListID = System.Environment.GetEnvironmentVariable("clientsListID", EnvironmentVariableTarget.Process);
            
           return configValues;
        }

        public static GraphServiceClient getGraphClient(ConfigurationsValues configValues)
        {
            IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
           .Create(configValues.Clientid)
           .WithTenantId(configValues.Tenantid)
           .WithClientSecret(configValues.ClientSecret)
           .Build();
            ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);
            GraphServiceClient graphClient = new GraphServiceClient(authProvider);
            return graphClient;
        }

    }

    public class ConfigurationsValues
    {
        public string Clientid { get; set; }
        public string Tenantid { get; set; }
        public string ClientSecret { get; set; }
        public string SiteId { get; set; }
        public string TargetedListId { get; set; }
        public string clientsListID { get; set; }
    }
}

Note - You have to make sure you have columns like Title and Name exist in the list where need to query.

Test the Project

Run the Project using F5 and make sure you are seeing below the window

Go to browser and enter URL

localhost:7071/api/Function1

You  would see the below message in the browser window

Go to the console window and see if it is logged data from the SharePoint list.

Hope this helps...Happy coding..!!!


Similar Articles