Skip to main content

SharePoint Framework extensions to Call Azure Function


In this article, we will talk about prerequisites, how to call Azure Function from SPFX extension, How to Create HHTP function, connect Visual Styuid editor to Azure and publish them, and Set Up CORS on the Azure Function, Create SharePoint Framework Extension, Azure Function, etc.


Prerequisites : 


Follow the below steps to create Azure Functions in the Azure portal. 

Steps by steps guide: https://docs.microsoft.com/en-us/sharepoint/dev/spfx/use-aadhttpclient-enterpriseapi 

 

Reference : https://docs.microsoft.com/en-us/answers/questions/430645/how-to-access-sharepoint-rest-api-in-my-function-a.html


Step-1: Login to Azure Portal (https://portal.azure.com/)

 

Step-2: As highlighted below, click on the  + Create a resource, and click on “Compute”. Now, choose the “Function App”.

 

How To Create Azure Function Apps In The Azure Portal

Or, for the same Option, you can search for the Function App and click on the search result.

Azure Function Creation using Azure Portal

 

From the next step onwards, You can follow my article to create the Azure Function App using the Azure Portal to create the Azure Function App. Assuming Your Azure Function App is ready.

 

Now the time to create the HTTP triggered Azure Function, since our Azure Function App is ready.

 

Click on the Functions link from the left navigation and then click the + Add button to create the Azure Function.

 

Select the HTTP trigger template and then Provide the name and choose the Authorization level as Anonymous and then click on the Create Function button.

 

Call Azure Function from Sharepoint Framework

Thsi how my code looks like you can wite your code Funtion 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 Microsoft.SharePoint.Client;

using OfficeDevPnP.Core;

using Microsoft.Online.SharePoint.TenantAdministration;



namespace Spo.Site.Provisioning

{

    public static class SiteProvisioning

    {

        //static string SiteUrl = string.Empty;


        //static string SiteTitle = string.Empty;

        [FunctionName("SiteProvisioning")]

        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 requestBody = await new StreamReader(req.Body).ReadToEndAsync();


            //

            var authManager = new AuthenticationManager();


            //

            try

            {

                //string SiteUrl = "https://rivian-admin.sharepoint.com";

                //using (var context = authManager.GetSharePointOnlineAuthenticatedContextTenant(SiteUrl, "test@conso.com", "password"))

                //{

                    //

                  //  log.LogError("Something went wrong when updating banner flag.");

               // }

                var AppCatalogSPListURL = "https://abc.sharepoint.com/sites/ApproveApps";

                var SiteUrl = "Addyours site url";

                string AppID = "Addyours AppID  ";

                string AppSecret = "Addyours AppSecret  ";


                OfficeDevPnP.Core.AuthenticationManager authManager = new OfficeDevPnP.Core.AuthenticationManager();

                ClientContext oClientContext = authManager.GetAppOnlyAuthenticatedContext(SiteUrl, AppID, AppSecret);

                log.LogError("Something went wrong when updating banner flag.");

                ClientContext oClientContextAppCatalog = authManager.GetAppOnlyAuthenticatedContext(AppCatalogSPListURL, AppID, AppSecret);



            }

            catch (Exception exception)

            {

                log.LogError("Something went wrong when updating banner flag." + exception.ToString());


            }

            return new OkObjectResult("kkll");

        }


    }

       

}


Extention Code 

Copy code code to your TS file make sure update interface  and Azure funtion Url

import { Version } from '@microsoft/sp-core-library';

import {

  BaseClientSideWebPart,

  IPropertyPaneConfiguration,

  PropertyPaneTextField

} from '@microsoft/sp-webpart-base';

import { escape } from '@microsoft/sp-lodash-subset';

import { HttpClient, SPHttpClient, HttpClientConfiguration, HttpClientResponse, ODataVersion, IHttpClientConfiguration, IHttpClientOptions, ISPHttpClientOptions } from '@microsoft/sp-http';

import styles from './AzureFunctionWebPartWebPart.module.scss';

import * as strings from 'AzureFunctionWebPartWebPartStrings';

import { IData } from './IData';


export interface IDemoAzureFunctionWebPartWebPartProps {

  description: string;

}


export default class AzureFunctionWebPartWebPart extends BaseClientSideWebPart<IAzureFunctionWebPartWebPartProps> {


  protected functionUrl: string = "https://abc.azurewebsites.net/api/CallHttpTrigger"; - need to update accodring to yours Azure funtion Url 


  protected DemoAzureFunction(): void {

      const requestHeaders: Headers = new Headers();

      requestHeaders.append("Content-type", "text/plain");

      requestHeaders.append("Cache-Control", "no-cache");


      var siteUrl: string = this.context.pageContext.web.absoluteUrl;

      var userName: string = (<HTMLInputElement>document.getElementById("txtUserName")).value;


      console.log(`SiteUrl: '${siteUrl}', UserName: '${userName}'`);


      const postOptions: IHttpClientOptions = {

        headers: requestHeaders,

        body: `{ name: '${userName}' }`

      };


      let responseText: string = "";

      let resultMsg: HTMLElement = document.getElementById("responseContainer");


      this.context.httpClient.post(this.functionUrl, HttpClient.configurations.v1, postOptions).then((response: HttpClientResponse) => {

         response.json().then((responseJSON: IData) => {

            //responseText = JSON.stringify(responseJSON);

            if (response.ok) {

                resultMsg.style.color = "white";

            } else {

                resultMsg.style.color = "red";

            }


            resultMsg.innerText = responseJSON.name;

          })

          .catch ((response: any) => {

            let errMsg: string = `WARNING - error when calling URL ${this.functionUrl}. Error = ${response.message}`;

            resultMsg.style.color = "red";

            console.log(errMsg);

            resultMsg.innerText = errMsg;

          });

      });

  }


  public render(): void {

    this.domElement.innerHTML = `

      <div class="${ styles.azureFunctionWebPart }">

        <div class="${ styles.container }">

          <div class="${ styles.row }">

            <div class="${ styles.column }">

              <span class="${ styles.title }">Call Azure Function</span>

              <p class="${ styles.subTitle }">Customize SharePoint experiences using Web Parts.</p>


              <div class="${styles.row}">

                <span class="ms-font-l ms-fontColor-white ${styles.label}">User name:</span>

                <input type="text" id="txtUserName"></input>

              </div>


              <button id="btnCallAzureFunction" class="${styles.button}">Say Hello!</button>

              <div id="responseContainer" class="${styles.label}"></div>


            </div>

          </div>

        </div>

      </div>`;


      document.getElementById("btnCallAzureFunction").onclick = this.callAzureFunction.bind(this);

  }


  protected get dataVersion(): Version {

    return Version.parse('1.0');

  }


  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {

    return {

      pages: [

        {

          header: {

            description: strings.PropertyPaneDescription

          },

          groups: [

            {

              groupName: strings.BasicGroupName,

              groupFields: [

                PropertyPaneTextField('description', {

                  label: strings.DescriptionFieldLabel

                })

              ]

            }

          ]

        }

      ]

    };

  }

}

Use the gulp-build command and Build your code & test 



Comments

Popular posts from this blog

Responsive design for Seattle.master in SharePoint 2013 and SharePoint Online.

/* =SharePoint Experts, Inc. - CSS for creating a responsive design for Seattle.master in SharePoint 2013 and SharePoint Online. For more details see the related blog post at http://blog.sharepointexperience.com/2015/03/making-seattle-master-responsive -Copyright SharePoint Experts, Inc. and Heather Solomon. Distributed to the public for reference and educational purposes. Code may be used as long as this copyright message stays intact. -sharepointexperience.com */ /* Font Awesome is a free font. http://fontawesome.io Check for latest version at http://fontawesome.io/get-started This should be moved to the top of your CSS file, irregardless of media queries */ @import "//netdna.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.css"; @media screen and (max-width: 1044px) { /* Hide unnecessary page elements */ .ms-core-listMenu-horizontalBox .ms-listMenu-editLink  /* Global navigation "Edit Links" when managed navigation is in use */ { displa