Powered By Blogger

Sunday, November 27, 2022

How to connect SharePoint with Azure Functions?

 1. To connect Azure Functions to SharePoint, you need to first create an "Azure Functions" class library.


2. Click "Next" and Type the Project Name, Location, Solution, and Solution Name.


3. Click "Next" and Select ".NET Framework" for Functions Worker, and select your trigger and access rights.


Note: Below are the type of Triggers and Access Rights present in the Azure Functions:-

Triggers:


a) Empty
b) Blob Trigger
c) Cosmos DB Trigger
d) Event Grid trigger
e) Event Hub trigger
f) Face locator
g) Generic WebHook
f) GitHub commenter
g) GitHub WebHook
h) Http GET CRUD
i) Http POST CRUD
j) Http PUT CRUD
k) Http trigger
l) Http trigger with parameters
m) Image resizer
n) IoT Hub Trigger
o) Queue trigger
p) SAS token
q) SendGrid
r) Service Bus Queue trigger
s) Service Bus Topic trigger
t) Timer trigger

Access Rights:


a) Function
b) Anonymous
c) Admin

4) Click "Create"

5) After creating an Azure Functions solution, you need to install the SharePoint package to connect via Azure Functions. The following package you need to install in the solution: Microsoft.SharePointOnline.CSOM


6) Now, type the code below to connect it to SharePoint:

using System.Globalization;
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.SharePoint.Client;

namespace AzureFunctions
{
    public static class MySharePointConnectorDemo
    {
        [FunctionName("MySharePointConnectorDemo")]
        public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestMessage req, TraceWriter log)
        {
            log.Info("C# HTTP trigger function processed a request.");

            Uri webSPOUrl = null;
            string folderName = null;

            // parse query parameter
            string name = req.GetQueryNameValuePairs()
                .FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
                .Value;

            if (name == null)
            {
                // Get request body
                dynamic data = await req.Content.ReadAsAsync<object>();
                name = data?.name;
            }

            string sharePointURL = "Your SharePoint URL";
            string myUserName = "Your UserName";
            string mypassword = "Your Pass";

            webSPOUrl = new Uri(Convert.ToString(sharePointURL, CultureInfo.InvariantCulture));
            string password = Convert.ToString(mypassword, CultureInfo.InvariantCulture);
            string userName = Convert.ToString(myUserName, CultureInfo.InvariantCulture);

            string entityDocumentLocationUrl = name;
            folderName = entityDocumentLocationUrl;
            string[] folderNameParts = folderName.Split(new char[] { '/' });

            folderName = folderName.Remove(0, folderName.IndexOf("/") + 1);

            using (ClientContext clientContext = new ClientContext(webSPOUrl))
            {

                SecureString securePassword = new SecureString();

                foreach (char c in mypassword.ToCharArray()) securePassword.AppendChar(c);

                clientContext.AuthenticationMode = ClientAuthenticationMode.Default;
                clientContext.Credentials = new SharePointOnlineCredentials(userName, securePassword);
                string fullPath = string.Empty;
                int retryCount = 10;
                int delay = 20;

                if (clientContext != null)
                {
                    if (folderNameParts[0].ToString() != string.Empty)
                    {
                        var lib = clientContext.Web;
                        clientContext.Load(lib);
                        clientContext.Load(lib.RootFolder);
                        ExecuteQueryWithIncrementalRetry(clientContext, retryCount, delay, log);
                    }
                }

            }

            return name == null
                ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a name on the query string or in the request body")
                : req.CreateResponse(HttpStatusCode.OK, "Hello " + name + " through VS");
        }

        public static void ExecuteQueryWithIncrementalRetry(ClientContext clientContext, int retryCount, int delay, TraceWriter log)
        {
            int retryAttempts = 0;
            int backoffInterval = delay;
            int retryAfterInterval = 0;
            bool retry = false;
            ClientRequestWrapper wrapper = null;
            if (retryCount <= 0)
                throw new ArgumentException("Provide a retry count greater than zero.");
            if (delay <= 0)
                throw new ArgumentException("Provide a delay greater than zero.");

            // Do while retry attempt is less than retry count
            while (retryAttempts < retryCount)
            {

                try
                {
                    if (!retry)
                    {
                        log?.Info("Calling ExecuteQuery - First try");
                        clientContext.ExecuteQuery();
                        return;
                    }
                    else
                    {
                        //increment the retry count
                        retryAttempts++;

                        // retry the previous request using wrapper
                        if (wrapper != null && wrapper.Value != null)
                        {
                            if (log != null) log.Info(string.Format("Calling wrapper RetryQuery - retry {0} out of {1}", retryAttempts, retryCount));
                            clientContext.RetryQuery(wrapper.Value);
                            return;
                        }
                        // retry the previous request as normal
                        else
                        {
                            if (log != null) log.Info(string.Format("Calling ExecuteQuery - retry {0} out of {1}", retryAttempts, retryCount));
                            clientContext.ExecuteQuery();
                            return;
                        }
                    }
                }
                catch (WebException ex)
                {
                    if (log != null) log.Info("WebException occured");

                    var response = ex.Response as HttpWebResponse;
                    // Check if request was throttled - http status code 429
                    // Check is request failed due to server unavailable - http status code 503
                    if (response != null && (response.StatusCode == (HttpStatusCode)429 || response.StatusCode == (HttpStatusCode)503))
                    {
                        if (log != null) log.Info("Status code: " + response.StatusCode.ToString());

                        wrapper = (ClientRequestWrapper)ex.Data["ClientRequest"];
                        retry = true;

                        // Determine the retry after value - use the 'Retry-After' header when available
                        string retryAfterHeader = response.GetResponseHeader("Retry-After");
                        if (!string.IsNullOrEmpty(retryAfterHeader))
                        {
                            if (log != null) log.Error("Using Retry-After header value");

                            if (!Int32.TryParse(retryAfterHeader, out retryAfterInterval))
                            {
                                retryAfterInterval = backoffInterval;
                            }
                        }
                        else
                        {
                            retryAfterInterval = backoffInterval;
                        }

                        if (log != null) log.Error("Delay execution for " + retryAfterInterval + " seconds before retry attempt: " + (retryAttempts + 1));

                        // Delay for the requested seconds
                        Thread.Sleep(retryAfterInterval * 1000);

                        // Increase counters
                        backoffInterval = backoffInterval * 2;
                    }
                    else
                    {
                        throw;
                    }
                }
            }
            throw new MaximumRetryAttemptedException($"Maximum retry attempts {retryCount}, has be attempted.");
        }

        [Serializable]
        public class MaximumRetryAttemptedException : Exception
        {
            public MaximumRetryAttemptedException(string message) : base(message) { }
        }

    }
}


No comments:

Post a Comment

Tools for Unit Testing in Power Platform