Cloud development - All about M365, .NET, SharePoint and more…
About Me
Contact Me
  • About Me
  • Contact Me
Cloud development - All about M365, .NET, SharePoint and more…
Development

Mastering SharePoint Online REST APIs A Step-by-Step Guide

In this era of digital collaboration, SharePoint Online provides a powerful platform for organisations to share and manage content. To take things up a notch, SharePoint offers REST APIs, allowing developers to interact with SharePoint data and capabilities programmatically.

In this blog post, we will delve into the world of SharePoint Online REST APIs, giving you a step-by-step guide on how to use them effectively.

What is a REST API?

REST stands for Representational State Transfer. It is an architectural style for designing networked applications. A REST API leverage’s HTTP methods (GET, POST, PUT, DELETE) to perform operations and exchange data in formats like JSON or XML.

SharePoint Online REST API: An Overview

SharePoint Online REST API facilitates interaction with SharePoint data from a remote client using web technologies. It is easy to work with and can be called from any platform that supports HTTP.

Let’s Dive In

Step 1: Register an App in Azure AD

To interact with SharePoint Online REST APIs, you’ll need to register an application in Azure Active Directory (AD) and grant the necessary permissions. Here’s how:

  1. Log into the Azure Portal and navigate to Azure Active Directory.
  2. Under Manage, select “App registrations” and click “New registration”.
  3. Enter a name for your app, select the appropriate account type, and click “Register”.
  4. After registering, copy the Application (client) ID. You’ll need this later.

Step 2: Grant API Permissions to the App

Once your app is registered, you need to grant permissions to access SharePoint data.

  1. In your App’s page, go to “API permissions” and click “Add a permission”.
  2. Select “SharePoint” and choose “Delegated permissions”.
  3. Check the permissions you need. For example, “AllSites.Write” if your app should be able to write data to all sites.
  4. Don’t forget to click on “Grant admin consent for {your organization}”.

Step 3: Generate a Secret Key

To authenticate your app when calling the SharePoint Online REST API, you’ll need a secret key.

  1. Go to Certificates and secrets and click on New client secret
  2. Enter a description and an expiration period for the secret, then click Add
  3. Copy the secret value and keep it somewhere safe. You won’t be able to see it again.

Now, you have everything you need to authenticate your app with SharePoint Online.

Step 4: Constructing SharePoint REST API Endpoints

The structure of SharePoint REST API endpoints is pretty consistent, making it easier to work with. Here is an example:

https://{site_url}/_api/web/lists/GetByTitle('List Name')/items
<pre class="wp-block-syntaxhighlighter-code">
This endpoint would return a list of all items from the specified list.

Step 5: Calling SharePoint REST API

Let’s use PowerShell for calling SharePoint REST APIs. Below is an example script to get all items from a specific list.

 

# Define your app's details and your site URL
$tenantId = "your-tenant-id"
$clientId = "your-app-client-id"
$clientSecret = "your-app-client-secret"
$resource = "https://your-domain.sharepoint.com"
$siteUrl = "https://your-domain.sharepoint.com/sites/your-site"
$tokenEndpoint = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
# Prepare the request body for the token request
$body = @{
    client_id     = $clientId
    scope         = "https://graph.microsoft.com/.default"
    client_secret = $clientSecret
    grant_type    = "client_credentials"
}
# Request the token
$response = Invoke-RestMethod -Uri $tokenEndpoint -Method Post -Body $body
$accessToken = $response.access_token
# Define the API endpoint
$apiEndpoint = "$siteUrl/_api/web/lists/GetByTitle('Documents')/items"
# Prepare the request headers
$headers = @{
    Authorization = "Bearer $accessToken"
    Accept = "application/json;odata=nometadata"
}
# Call the SharePoint REST API
$items = Invoke-RestMethod -Uri $apiEndpoint -Method Get -Headers $headers
# Output the items
$items.value
<pre class="wp-block-syntaxhighlighter-code">

This script retrieves a list of all items from the Documents list on your SharePoint site and outputs them.

 

Conclusion

Mastering SharePoint Online REST APIs can supercharge your SharePoint implementations, as it allows for powerful integrations and automation. While this post serves as a basic primer, the REST API’s capabilities are extensive, so I encourage further exploration to take full advantage of what it offers. Remember to secure your application’s Client ID and Secret, as they are essentially the keys to your kingdom. Handle them with care, just as you would with any sensitive data. Happy coding!

June 4, 2023by Luke
Development, Latest

Building SharePoint Online Remote Event Receivers for Document Review Flows

SharePoint Online has provided a myriad of collaboration and productivity tools for businesses. Among these, Remote Event Receivers and Microsoft Flow (now known as Power Automate) stand out as potent tools for automation and integration.

In this blog post, we will demonstrate how to use SharePoint Online Remote Event Receivers in combination with Power Automate to trigger a review Flow whenever a document’s status is set to “Pending” in a Document Library.

Understanding the Concepts

SharePoint Online Remote Event Receivers

Remote Event Receivers are components that handle events such as additions, updates, and deletions in SharePoint Online. Unlike their counterparts in SharePoint Server, they handle events remotely, meaning they respond to events in SharePoint Online from an external web service.

Power Automate (Flow)

Power Automate is a service offered by Microsoft that allows creation of automated workflows between apps and services to synchronise files, get notifications, collect data, and more.

Getting Started

The process is fairly straightforward and consists of the following steps:

  1. Creating an Azure Function
  2. Creating a Remote Event Receiver
  3. Creating a Power Automate Flow
  4. Attaching the Event Receiver to the Document Library

Please Note: The solution described in this post assumes you have access to and basic knowledge of Azure Functions, SharePoint Online, and Power Automate.

Step 1: Creating an Azure Function

Azure Functions is a serverless solution that allows you to write less code, maintain less infrastructure, and save costs. We’ll use it to host our Remote Event Receiver.

  1. Log into the Azure Portal.
  2. Create a new Function App.
  3. Once the Function App is created, create a new function within it. Use the HTTP trigger template, name your function and choose the Authorisation level (Function level should suffice).

Here is a basic example of how to structure your function:

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    string content = await req.Content.ReadAsStringAsync();
    log.Info(content);
    // Add your code to trigger the Power Automate flow here
    return req.CreateResponse(HttpStatusCode.OK);
}

This function merely logs the incoming request content and returns an OK response. You will add the logic to trigger the Power Automate flow later.

Step 2: Creating a Remote Event Receiver

In SharePoint, go to the list settings for the Document Library you want to use. Under “General Settings”, click on “Advanced settings”, and allow the management of content types by choosing “Yes”.

Now, add a new column to the Document content type. Name it “Status” and make it a Choice type field with “Pending” as one of the choices.

Once done, we will add our Remote Event Receiver. SharePoint does not provide an out-of-the-box interface to add Remote Event Receivers to lists or content types, so you will have to use the Client Side Object Model (CSOM) to attach the Event Receiver to the list.

Here is an example PowerShell script using CSOM to attach the Event Receiver to your Document Library:

# Input parameters
$siteUrl = "https://your-domain.sharepoint.com/sites/your-site"
$listTitle = "Documents"
$username = "your-username@your-domain.com"
$password = "your-password"
$securePassword = ConvertTo-SecureString -String $password -AsPlainText -Force
$credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $securePassword
$addInOnly = $False
# Connect to the site
Connect-PnPOnline -Url $siteUrl -Credentials $credentials -CreateDrive
# Define the event receiver properties
$eventReceiverName = "ItemUpdated"
$eventReceiverUrl = "https://your-azure-function-url"
$eventReceiverType = [Microsoft.SharePoint.Client.EventReceiverType]::ItemUpdated
$synchronization = [Microsoft.SharePoint.Client.EventReceiverSynchronization]::Asynchronous
# Add the event receiver
Add-PnPEventReceiver -List $listTitle -Name $eventReceiverName -Url $eventReceiverUrl -EventReceiverType $eventReceiverType -Synchronization $synchronization

This script adds an ItemUpdated event receiver to your Document Library. This event receiver will trigger your Azure Function whenever an item in the Document Library is updated.

Step 3: Creating a Power Automate Flow

Next, we’ll create a Power Automate flow that will be triggered by the Azure Function whenever a document status is set to “Pending”.

  1. Go to Power Automate.
  2. Create a new Flow. Use the HTTP request trigger.
  3. Add a new step to send an email (or any other action you want the Flow to take).
  4. Save your Flow. You will be provided with an HTTP POST URL.

Step 4: Finalizing the Azure Function

Finally, we will modify the Azure Function to trigger the Power Automate flow whenever a document’s status is set to “Pending”.

  1. In the Azure Function, add logic to parse the incoming request content to get the item data.
  2. Check if the item’s status is set to “Pending”.
  3. If it is, send a POST request to the Power Automate flow’s URL to trigger the flow.

Here is the modified Azure Function:

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    string content = await req.Content.ReadAsStringAsync();
    log.Info(content);
    // Parse the content as XML
    var doc = new XmlDocument();
    doc.LoadXml(content);
    var mgr = new XmlNamespaceManager(doc.NameTable);
    mgr.AddNamespace("s", "http://schemas.microsoft.com/sharepoint/soap/");
    mgr.AddNamespace("z", "#RowsetSchema");
    // Get the item data
    var itemDataNode = doc.SelectSingleNode("//s:Changes/s:Object/s:Properties/s:SharedFields", mgr);
    var itemData = itemDataNode.ChildNodes.Cast<XmlNode>().ToDictionary(n => n.LocalName, n => n.InnerText);
    // Check if the item's status is set to "Pending"
    if (itemData.ContainsKey("Status") && itemData["Status"] == "Pending")
    {
        // Trigger the Power Automate flow
        var flowUrl = "https://your-power-automate-flow-url";
        await new HttpClient().PostAsync(flowUrl, new StringContent(""));
    }
    return req.CreateResponse(HttpStatusCode.OK);
}

That’s it! You have now successfully set up a Remote Event Receiver in SharePoint Online that triggers a Power Automate flow whenever a document’s status is set to “Pending”.

This post provided a step-by-step guide on setting up this process, however, please note that this is a simplistic example and a real-world scenario would potentially be more complex.

June 4, 2023by Luke
Development

Working with SharePoint Online REST Search API 101

In SharePoint Online, the REST Search API is a powerful tool to query against SharePoint’s search index. It provides a comprehensive way to interact with SharePoint’s search capabilities programmatically. This blog post will guide you on how to use the SharePoint Online REST Search API to find, open, and view documents based on their metadata fields using the Graph API.

We’ll proceed in the following steps:

  1. Introduction to SharePoint Online REST Search API
  2. Authenticating with Microsoft Graph API
  3. Searching for Documents Based on Metadata
  4. Opening and Viewing Documents

You can use a tool like Postman to send these requests. The basics of sending POST or GET requests via REST API’s are not covered here, it’s expected you know how to set headers etc. as well.

Step 1: Introduction to SharePoint Online REST Search API

SharePoint Online REST Search API allows you to submit search queries and get search results programmatically. This API is useful for retrieving SharePoint data based on specific conditions or filters.

The primary endpoint of the REST Search API is /_api/search/query. This endpoint accepts various parameters to refine the search query, and returns results in JSON format.

Step 2: Authenticating with Microsoft Graph API

To interact with the REST Search API, you must first authenticate your application with Microsoft Graph API. You can do this by registering your application in Azure Active Directory (Azure AD) and obtaining an access token.

Here’s a brief overview of the steps involved:

  1. Register an application in the Azure portal.
  2. After registration, note the Application (client) ID and Directory (tenant) ID.
  3. Generate a new client secret under Certificates & secrets.
  4. Grant API permissions for SharePoint under API permissions.
  5. Get an access token. Send a POST request to the following URL:
https://login.microsoftonline.com/&lt;tenant-id>/oauth2/v2.0/token

Replace <tenant-id> with your Azure AD tenant ID.

The request body should include:

  • client_id: your application’s Client ID
  • scope: “https://graph.microsoft.com/.default“
  • client_secret: your application’s Client Secret
  • grant_type: “client_credentials”

The response will include an access_token. Use this token to authenticate your requests to the SharePoint REST Search API. An example in PowerShell which you could easily replicate in Postman for getting a auth token:

# Define the tenant ID, client ID and secret
$tenantId = "<tenant-id>"
$clientId = "<client-id>"
$clientSecret = "<client-secret>"
# Define the resource and token endpoint
$resource = "https://graph.microsoft.com"
$tokenEndpoint = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
# Prepare the request body
$body = @{
    client_id     = $clientId
    scope         = "https://graph.microsoft.com/.default"
    client_secret = $clientSecret
    grant_type    = "client_credentials"
}
# Request the token
$response = Invoke-RestMethod -Uri $tokenEndpoint -Method Post -Body $body
# Output the access token
Write-Output "Access Token: $($response.access_token)"

Step 3: Searching for Documents Based on Metadata

You can now send authenticated GET requests to the REST Search API endpoint. The search query string goes in the querytext parameter, and you can use other parameters to refine the search.

To find documents authored by a specific user, send a GET request to:

https://&lt;site-url>/_api/search/query?querytext='Author:&lt;author-name>+AND+IsDocument:True'

Replace <site-url> with your SharePoint site URL and <author-name> with the actual author’s name.

Include the access_token in the Authorization header:

GET /_api/search/query?querytext='Author:&lt;author-name>+AND+IsDocument:True' HTTP/1.1
Host: &lt;site-url>
Authorization: Bearer &lt;access_token>
Accept: application/json;odata=nometadata

A script that could use the token generated above would look something like:

# Define the SharePoint Online REST Search API endpoint and query
$siteUrl = "<site-url>"
$searchEndpoint = "https://$siteUrl/_api/search/query?querytext='IsDocument:True+AND+Author:John'"
# Prepare the request headers with the access token
$headers = @{
    Authorization = "Bearer $accessToken"
    Accept = "application/json;odata=nometadata"
}
# Send the authenticated GET request to the SharePoint Online REST Search API
$searchResponse = Invoke-RestMethod -Uri $searchEndpoint -Method Get -Headers $headers
# Output the search results
Write-Output $searchResponse

Step 4: Opening and Viewing Documents

The search results contain various properties for each document, including the document’s URL in the Path field. To open a document, copy the Path value and paste it into a web browser.

You’ve now learned how to use the SharePoint Online REST Search API to find, open, and view documents based on their metadata fields using the Graph API. By mastering these steps, you can efficiently interact with SharePoint Online programmatically. Happy coding!

June 4, 2023by Luke
Development, Latest, SharePoint

Using the SPO Search REST API to create a Webpart showing Recently Modified Documents containing specific keywords

SharePoint Online provides a powerful Search API that allows developers to query against SharePoint’s search index. In this blog post, we will create a custom web part that utilizes the Search API to retrieve and display the most recently modified documents matching specific keywords.

Our tool of choice for developing custom SharePoint Online web parts is the SharePoint Framework (SPFx). We will write our web part in TypeScript and use ReactJS for the front-end. To follow along, ensure you have administrative access to your SharePoint Online and Office 365 environment.

Here’s our roadmap:

  1. Setup the Development Environment
  2. Create a New SharePoint Framework Solution
  3. Develop the Web Part
  4. Deploy and Test the Web Part

Step 1: Setup the Development Environment

Firstly, we need to setup our development environment. This involves installing Node.js, Yeoman SharePoint generator, and Gulp. You can install these dependencies with the following commands:

npm install -g yo gulp
npm install -g @microsoft/generator-sharepoint

Step 2: Create a New SharePoint Framework Solution

After setting up the environment, navigate to the folder where you want to create the solution and run the following command:

yo @microsoft/sharepoint

When prompted:

  • For the solution name, enter “DocumentSearchWebPart”
  • Choose “Use the current folder” for where to place the files
  • Choose “Y” to allow tenant admin to deploy the solution to all sites immediately
  • Choose “N” for unique permissions to access web APIs
  • Choose “WebPart” as the component type
  • For the web part name, enter “DocumentSearch”
  • For the description, enter “A web part that displays recently modified documents based on search keywords”
  • For the framework, choose “React”

Step 3: Develop the Web Part

After creating the solution, navigate to the src/webparts/documentSearch/components/DocumentSearch.tsx file. This is where we’ll write the code to fetch and display documents from the SharePoint Search API.

import * as React from 'react';
import { IDocumentSearchProps } from './IDocumentSearchProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
export interface IDocumentSearchState {
  results: any[];
}
export default class DocumentSearch extends React.Component<IDocumentSearchProps, IDocumentSearchState> {
  constructor(props: IDocumentSearchProps) {
    super(props);
    this.state = {
      results: []
    };
  }
  public componentDidMount() {
    const keywords = 'your-keywords'; // replace this with your keywords
    this.props.context.spHttpClient.get(`${this.props.context.pageContext.web.absoluteUrl}/_api/search/query?querytext='FileType:docx+AND+${escape(keywords)}'&sortlist='LastModifiedTime:descending'&rowlimit=10`, SPHttpClient.configurations.v1)
      .then((response: SPHttpClientResponse) => {
        return response.json();
      })
      .then((json) => {
        this.setState({ results: json.PrimaryQueryResult.RelevantResults.Table.Rows });
      });
  }
  public render(): React.ReactElement<IDocumentSearchProps> {
    return (
      <div>
        {this.state.results.map((result, index) => {
          const cells = result.Cells.map((cell) => {
            return cell.Value;
          });
          return (
            <div key={index}>
              <h3>{cells.Title}</h3>
              <p>Last Modified: {new Date(cells.LastModifiedTime).toLocaleString()}</p>
              <a href={cells.Path}>Open Document</a>
            </div>
          );
        })}
      </div>
    );
  }
}

Here, we’re making a GET request to the SharePoint Search API, passing our query text and sort order as parameters. The query text includes the file type (docx in this case) and our search keywords, and we’re sorting the results by Last Modified Time in descending order, which will give us the most recently modified documents first. We’re limiting the results to the top 10.

Step 4: Deploy and Test the Web Part

Finally, we will deploy and test our web part.

To bundle the web part, run the following command:

gulp bundle --ship

And to package the solution:

gulp package-solution --ship

These commands create a .sppkg package in the sharepoint/solution folder. Upload this package to the SharePoint App Catalog. You can now add the web part to a page by editing the page and clicking the ‘+’ button to add a new web part.

And there you have it, a custom SharePoint Online web part that utilises the SharePoint Search API to display the most recently modified documents that match specific keywords. You can further customise this web part as needed. Happy coding!

June 4, 2023by Luke
Development, SharePoint

Creating a Custom SharePoint Online Webpart to Display Contact Details with Photos

One of the powerful capabilities of SharePoint Online is its ability to create and utilize custom web parts. These web parts can help to extend the platform’s functionalities to meet specific organizational needs. In this tutorial, we will walk you through the process of creating a custom web part that displays user contact details along with their photos.

Our web part will be created using the SharePoint Framework (SPFx), which is a page and web part model for SharePoint Online. We’ll use TypeScript for the back-end, and ReactJS for the front-end. The entire process involves the following steps:

  1. Setting up the Development Environment
  2. Creating a New SharePoint Framework Solution
  3. Developing the Web Part
  4. Deploying and Testing the Web Part

Please make sure you have administrative access to the SharePoint Online and Office 365 environment. Let’s get started.

Step 1: Setting up the Development Environment

To set up your SharePoint Framework development environment, you will need Node.js, Yeoman, and the SharePoint client-side solution generator, and Gulp. Open a command prompt and run the following commands to install these dependencies:

npm install -g yo gulp
npm install -g @microsoft/generator-sharepoint

Step 2: Creating a New SharePoint Framework Solution

Now, let’s create a new SharePoint Framework solution.

Navigate to the folder where you want to create the solution, and run the following command:

yo @microsoft/sharepoint

The Yeoman SharePoint generator will start prompting you for the following information:

  • What is your solution name?
  • Where do you want to place the files?
  • Do you want to allow the tenant admin the choice of being able to deploy the solution to all sites immediately without running any feature deployment or adding apps in sites?
  • Will the components in the solution require permissions to access web APIs that are unique and not shared with other components in the tenant?
  • Which type of client-side component to create?

For this example, choose the following:

  • Solution Name: UserContactWebPart
  • Baseline packages: Use the current folder
  • Deployment option: Select Y (Yes)
  • Permissions: N (No)
  • Component Type: WebPart
  • Web part name: UserContact
  • Description: A web part that displays user contact details
  • Framework: React

Step 3: Developing the Web Part

Navigate into the solution folder, and open the file src/webparts/userContact/components/UserContact.tsx

This file represents the frontend of your webpart.

You need to install the Microsoft Graph client library. To do this, run the following command:

npm install @microsoft/microsoft-graph-client

Now, let’s edit our UserContact.tsx file:

 --
import * as React from 'react';
import styles from './UserContact.module.scss';
import { IUserContactProps } from './IUserContactProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { MSGraphClient } from '@microsoft/sp-http';
export interface IUserContactState {
  users: any[];
}
export default class UserContact extends React.Component<IUserContactProps, IUserContactState> {
  constructor(props: IUserContactProps) {
    super(props);
    this.state = {
      users: []
    };
  }
  public componentDidMount() {
    this.props.context.msGraphClientFactory
      .getClient()
      .then((client: MSGraphClient): void => {
        // get users and their photos from Microsoft Graph
        client
          .api('/users')
          .version('v1.0')
          .get((err, res) => {
            if (err) {
              console.error(err);
              return;
            }
            this.setState({ users: res.value });
          });
      });
  }
  public render(): React.ReactElement<IUserContactProps> {
    return (
      <div className={styles.userContact}>
        {this.state.users.map((user, key) => {
          return (
            <div key={key}>
              <h2>{user.displayName}</h2>
              <p>{user.mail}</p>
              <img src={`/_layouts/15/userphoto.aspx?size=L&username=${user.mail}`} alt="User photo" />
            </div>
          );
        })}
      </div>
    );
  }
}

Step 4: Deploying and Testing the Web Part

Now that our web part is developed, let’s deploy and test it.

To build and bundle your web part, run the following command in your command prompt:

gulp bundle --ship

And to package the solution, use the following command:

gulp package-solution --ship

These commands create a .sppkg package in the sharepoint/solution folder. You can upload this package to the SharePoint App Catalog in your SharePoint Online site. After uploading, you can add your web part to a page by editing the page and clicking the ‘+’ button to add a new web part. Note you’ll need to have specific permissions assigned to query Graph API.

And there you have it, a custom SharePoint Online web part that displays user contact details along with their photos. You can customize this web part further as per your needs. Happy coding!

June 3, 2023by Luke
Development, SharePoint

How to Create a Custom Wall Posts Webpart in SharePoint 2016

SharePoint is a versatile platform for building solutions that can fulfill various business needs. One such feature is the ability to create a custom webpart, a reusable component that can be included in SharePoint sites to provide specific functionality. Today, we’ll be discussing how to create a custom Wall Posts webpart for SharePoint 2016.

Before we begin, we should note that our custom wall posts webpart will be created using Visual Studio 2019, which supports development for SharePoint 2016. We will be writing in C# and using JavaScript and CSS for the front-end. Please ensure you have the necessary permissions to create and deploy custom webparts in your SharePoint environment.

Step 1: Create a New Project

Open Visual Studio 2019 and create a new project.

  • Select File … New … Project.
  • In the New Project dialog, choose Visual C# … Office/SharePoint … SharePoint Add-in. Click Next.
  • Enter a name and location for your project and click Create.
  • In the “What SharePoint site do you want to use for debugging?” box, enter the URL of the SharePoint site you’re developing against, and then choose “Deploy as a farm solution”. Click Finish.

Step 2: Add a New Web Part Item

Next, we’ll add a new web part to the project:

  • In Solution Explorer, right-click on the project, go to Add, then New Item.
  • In the Add New Item dialog, choose Visual C# … Office/SharePoint … Web Part.
  • Give it a name like “WallPostsWebPart” and click Add.

Step 3: Code Your Web Part

You will now hae a new file in your project named WallPostsWebPart. This is where you’ll write the backend code for your webpart.

using System;
using System.ComponentModel;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Text;
namespace WallPostsWebPart.WallPostsWebPart
{
    [ToolboxItemAttribute(false)]
    public class WallPostsWebPart : WebPart
    {
        // Visual Studio might automatically update this path when you change the Visual Web Part project item.
        private const string _ascxPath = @"~/_CONTROLTEMPLATES/15/WallPostsWebPart/WallPostsWebPart/WallPostsWebPartUserControl.ascx";
        protected override void CreateChildControls()
        {
            Control control = Page.LoadControl(_ascxPath);
            Controls.Add(control);
        }
        
        // Fetching the wall posts
        public string GetWallPosts()
        {
            SPSite site = new SPSite("http://YourSharepointSite");
            SPWeb web = site.OpenWeb();
            SPList list = web.Lists["Posts"]; // This should be the name of your wall posts list
            SPQuery query = new SPQuery();
            query.Query = "<OrderBy><FieldRef Name='Created' Ascending='FALSE'/></OrderBy>"; // This orders the posts by creation date, newest first
            SPListItemCollection items = list.GetItems(query);
            
            StringBuilder sb = new StringBuilder();
            foreach(SPListItem item in items)
            {
                sb.Append("<p>");
                sb.Append(item["Title"].ToString()); // Assuming "Title" field holds the post content
                sb.Append("</p>");
            }
            return sb.ToString();
        }
    }
}

Step 4: Create the Front-End

Now, we need to create a user control to represent the front-end of our webpart. This is done in the “WallPostsWebPartUserControl.ascx” file.

And that’s it! Now, you can deploy the solution to your SharePoint site and add the webpart to a page to test it.

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="WallPostsWebPartUserControl.ascx.cs" Inherits="WallPostsWebPart.WallPostsWebPart.WallPostsWebPartUserControl" %>
<div id="wallPostsContainer">
    <%: this.GetWallPosts() %> <!-- This calls the GetWallPosts method we wrote in the code-behind -->
</div>

Step 5: Deploy the Solution

To deploy your custom webpart, follow these steps:

  • In Visual Studio, on the menu, select Build … Deploy Solution.
  • After the solution has been deployed, go to your SharePoint site and open a page where you want to add the webpart.
  • Click on the Page tab and then Edit.
  • Click on the Insert tab and then Web Part.
  • In the Categories list, click Custom, find your “WallPostsWebPart”, and then click Add.

Your custom Wall Posts webpart should now be visible on the SharePoint page.

In conclusion, creating a custom webpart in SharePoint allows you to create custom functionality and provide solutions specific to your business needs. The example above showcases a simple implementation of pulling wall posts, but the possibilities are endless. You can always expand and improve the functionality based on your requirements. Happy SharePointing!

June 3, 2023by Luke
Development, SharePoint

Creating a Custom Events Calendar Webpart for SharePoint 2016

SharePoint 2016, a platform developed by Microsoft, it provides robust capabilities for collaboration and document management. This blog post will guide you through the process of creating a custom events calendar webpart for SharePoint 2016, a feature that can help manage and display various organisational events. We’ll use JavaScript, SharePoint’s Client-Side Object Model (CSOM), and SharePoint’s REST API for this task.

Prerequisites:

Before we start, you will need:

  1. Access to a SharePoint 2016 site collection.
  2. Familiarity with JavaScript, HTML, and CSS.
  3. SharePoint Designer 2013 (It’s compatible with SharePoint 2016).
  4. Basic understanding of SharePoint’s REST API and CSOM.

Step 1: Set up the Calendar List

First, we need a Calendar List. If you already have one, you can skip this step. To create a Calendar List:

  1. On your SharePoint site, click on Site Contents … Add an App.
  2. Click on the Calendar tile and give it a name then hit Create.

Step 2: Create the WebPart

Now, let’s create the custom webpart. Follow these steps:

  1. Open SharePoint Designer and connect to your site.
  2. Go to File … New … WebPart and create a new web part.
  3. Paste the following base code into the .webpart file:
<webParts>
  <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
    <metaData>
      <type name="Microsoft.SharePoint.WebPartPages.ScriptEditorWebPart, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
      <importErrorMessage>Cannot import this Web Part.</importErrorMessage>
    </metaData>
    <data>
      <properties>
        <property name="Title" type="string">Custom Calendar WebPart</property>
        <property name="Description" type="string">This WebPart displays a custom events calendar.</property>
      </properties>
    </data>
  </webPart>
</webParts>

Step 3: Fetching Calendar Data with REST API

Next, we’ll use SharePoint’s REST API to fetch the calendar data. We’ll add the JavaScript code within the CDATA tags of the webpart file.

<![CDATA[
<script type="text/javascript">
  document.addEventListener('DOMContentLoaded', function(){
    var calendarListUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbytitle('Calendar')/items?$select=Title,EventDate,EndDate";
    fetch(calendarListUrl, {
      headers: {
        "accept": "application/json;odata=verbose"
      }
    })
    .then(response => response.json())
    .then(data => renderEvents(data.d.results))
    .catch(error => console.error('Error:', error));
  });
  function renderEvents(events){
    // Rendering code goes here
  }
</script>
]]>

This script runs when the DOM is fully loaded. It fetches calendar events and calls a function renderEvents with the events data.

Step 4: Rendering the Events

The renderEvents function will be responsible for rendering events data. We’ll use a simple HTML structure for this example, but you could use any UI library or framework. Script refused to post as text, I believe WordPress uses some of the same internal function names and tried to run it as an actual script, you’ll need to retype this!

function renderEvents(events){
  var eventsHTML = events.map(event => `
    <div class="event">
      <h3>${event.Title}</h3>
      <p>Start: ${new Date(event.EventDate).toLocaleString()}</p>
      <p>End: ${new Date(event.EndDate).toLocaleString()}</p>
    </div>
  `).join('');
  
  var calendarElement = document.getElementById('calendar');
  if (calendarElement) {
    calendarElement.innerHTML = eventsHTML;
  }
}

Step 5: Adding WebPart to a SharePoint Page

Finally, let’s add the custom webpart to a SharePoint page.

  1. Navigate to your SharePoint page and click Edit.
  2. Click on Insert … WebPart … Custom and select your custom webpart.
  3. Click on Add and your custom events calendar webpart should now appear on your page.

That’s it! You have successfully created a custom events calendar webpart for SharePoint 2016. Please note that the calendar’s appearance can be customised using CSS, and you can expand the script to include more features like event filtering, sorting, or pagination.

June 3, 2023by Luke
Development, SharePoint

Building a ‘Contacts’ web part

Ever wanted an easy way to pick people from your staff directory and display them on a page? Ever wanted to point this kind of web part at a AD security group and have it automatically display all the members? Then this web part is for you.

This is a on-premises web part, you’ll need Visual Studio and SharePoint installed to develop this. Start with a your project open and add a Visual Web Part . This doesn’t change between 2010 and 2019:

You will end up with the four standard files, note the extra CS file we’ll address that later:

So the ContactDetailsWebPart.cs looks like so:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.UI.WebControls.WebParts;
using YourNameSpaceWebParts.CONTROLTEMPLATES.YourNameSpace;
using Microsoft.SharePoint;
namespace YourNameSpaceWebParts.ContactDetailsWebPart
{
    [ToolboxItem(false)]
    public class ContactDetailsWebPart : WebPart, IWebEditable
    {
        // Visual Studio might automatically update this path when you change the Visual Web Part project item.
        private const string _ascxPath = @"~/_CONTROLTEMPLATES/15/YourNameSpace/ContactDetailsWebPartUserControl.ascx";
        public enum displayMode
        {
            BigPicture,
            SmallPicture,
            NoPicture
        }
        [WebBrowsable(true),
        WebDisplayName("Display Mode"),
        WebDescription(""),
        Personalizable(
        PersonalizationScope.Shared),
        Category("Custom Properties"),
        DefaultValue(displayMode.BigPicture)]
        public displayMode DisplayMode
        { 
            get;
            set;
        }
        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(false)]
        public string Contacts { get; set; }  

        #region IWebEditable Members
        EditorPartCollection IWebEditable.CreateEditorParts()
        {
            List<EditorPart> editors = new List<EditorPart> {new PeoplePickerEditor(ID)};
            return new EditorPartCollection(editors);
        }
        object IWebEditable.WebBrowsableObject
        {
            get { return this; }
        }
        #endregion

        protected override void CreateChildControls()
        {
            // Set username to current user adding Web Part by default
            if (String.IsNullOrEmpty(Contacts))
            {
                string loginname = SPContext.Current.Web.CurrentUser.LoginName;
                string[] loginnameArr = loginname.Split('\\');
                Contacts = loginnameArr[1];
            }
            ContactDetailsWebPartUserControl control = Page.LoadControl(_ascxPath) as ContactDetailsWebPartUserControl;
            if (control == null) return;
            control.wp = this;
            control.Username = Contacts;
            Controls.Add(control);
        }
    }
}

Elements.xml defines the what/where of this web part:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/" >
  <Module Name="ContactDetailsWebPart" List="113" Url="_catalogs/wp">
    <File Path="ContactDetailsWebPart\ContactDetailsWebPart.webpart" Url="YourNameSpace.WebParts_ContactDetailsWebPart.webpart" Type="GhostableInLibrary" ReplaceContent="TRUE" IgnoreIfAlreadyExists="FALSE">
      <Property Name="Group" Value="The Intranet" />
    </File>
  </Module>
</Elements>

The web part file can be customised next, again the title and description are the parts your end users will see:

&lt;?xml version="1.0" encoding="utf-8"?>
&lt;webParts>
  &lt;webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
    &lt;metaData>
      &lt;type name="YourNameSpace.WebParts.ContactDetailsWebPart.ContactDetailsWebPart, $SharePoint.Project.AssemblyFullName$" />
      &lt;importErrorMessage>$Resources:core,ImportErrorMessage;&lt;/importErrorMessage>
    &lt;/metaData>
    &lt;data>
      &lt;properties>
        &lt;property name="Title" type="string">Contact Details WebPart&lt;/property>
        &lt;property name="Description" type="string">Display integrated contact details for a selection of users.&lt;/property>
      &lt;/properties>
    &lt;/data>
  &lt;/webPart>
&lt;/webParts>

Now in Visual Studio add a new CS file, this will handle the custom logic required to handle the people picker control:

using Microsoft.SharePoint.WebControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
namespace YourNameSpace.WebParts.ContactDetailsWebPart
{
    public sealed class PeoplePickerEditor : EditorPart
    {
        private PeopleEditor _peoplePicker;
        public PeoplePickerEditor(string webPartID)
        {
            ID = "PeoplePickerEditor" + webPartID;
            Title = "Select Contacts";
        }
        protected override void CreateChildControls()
        {
            _peoplePicker = new PeopleEditor
            {
                ID = "pe1",
                AllowTypeIn = true,
                AllowEmpty = false,
                MultiSelect = true,
                Width = Unit.Pixel(250),
                SelectionSet =
                    PeopleEditor.AccountType.SecGroup.ToString() + "," + PeopleEditor.AccountType.SPGroup.ToString() +
                    "," + PeopleEditor.AccountType.User.ToString()
            };
            Controls.Add(_peoplePicker);
        }
        public override bool ApplyChanges()
        {
            EnsureChildControls();
            ContactDetailsWebPart webPart = WebPartToEdit as ContactDetailsWebPart;
            if (webPart != null)
            {
                webPart.Contacts = _peoplePicker.CommaSeparatedAccounts;
                //PickerEntity entity    
            }
            return true;
        }
        public override void SyncChanges()
        {
            EnsureChildControls();
            ContactDetailsWebPart webPart = WebPartToEdit as ContactDetailsWebPart;
            if (webPart != null)
            {
                _peoplePicker.CommaSeparatedAccounts = webPart.Contacts;
                //_peoplePicker.ResolvedEntities = webPart.Contacts;   
            }
        } 
    }
}

Now you should have a working web part if you compile and deploy your WSP package.

The title can be customised, the web part itself will show photos if you have them in your user profile service, it will show job title and phone number as well.

You can also control the picture via the web part properties. This for me seems like a nice way to automate an otherwise very manual admin task whenever a teams membership changes.

If you have role based groups setup that means your security groups for teams are automatically updated, then hooking them into this web part means your teams contact information will always be up to date!

African Grey Parrot
January 25, 2020by Luke
Development, SharePoint

Building a ‘News Posts’ web part

The idea for this web part is pretty basic, take a SharePoint out of the box Posts list such as you get from an out of the box Blog Site and point a custom web part at it to retrieve posts.

Use case could be your main Intranet news feed or on your community sites. Some additional cool bits and pieces are support for custom colours via any hex codes you care to use. Plus support for custom category filtering meaning you can put multiple copies of the web part on a page, and colour code the news based on it’s category!

This is a on-premises web part, you’ll need Visual Studio and SharePoint installed to develop this. Start with a your project open and add a Visual Web Part . This doesn’t change between 2010 and 2019:

Call it whatever you like. You’ll end up with four files:

Start with the C# file. We are basically just capturing our custom properties that we want to be able to set in the web part by the end user:

using System.ComponentModel;
using System.Web.UI.WebControls.WebParts;
using YournameSpace.WebParts.CONTROLTEMPLATES.Your.Namespace;
namespace YournameSpace.WebParts.GenericPostsWebpart
{
    [ToolboxItem(false)]
    public class GenericPostsWebpart : WebPart
    {
        [WebBrowsable(true),
        WebDisplayName("Enter Site URL"),
        WebDescription("Enter the server relative path to the site containing your posts list"),
        Personalizable(
        PersonalizationScope.Shared),
        Category("Custom Properties"),
        DefaultValue("")]
        public string siteurl
        {
            get;
            set;
        }
        [WebBrowsable(true),
        WebDisplayName("Enter List Name"),
        WebDescription("Enter the name of the list that you want to display posts from"),
        Personalizable(
        PersonalizationScope.Shared),
        Category("Custom Properties"),
        DefaultValue("Posts")]
        public string listname
        {
            get;
            set;
        }
        [WebBrowsable(true),
        WebDisplayName("Enter Post Limit"),
        WebDescription(""),
        Personalizable(
        PersonalizationScope.Shared),
        Category("Custom Properties"),
        DefaultValue("3")]
        public string postlimit
        {
            get;
            set;
        }
        [WebBrowsable(true),
        WebDisplayName("Enter Category (if required)"),
        WebDescription("Leave blank to show all"),
        Personalizable(
        PersonalizationScope.Shared),
        Category("Custom Properties"),
        DefaultValue("")]
        public string category
        {
            get;
            set;
        }
        [WebBrowsable(true),
        WebDisplayName("Title Link Colour"),
        WebDescription("Enter the hex colour value to use for the news titles"),
        Personalizable(
        PersonalizationScope.Shared),
        Category("Custom Properties"),
        DefaultValue("#00ACB8")]
        public string linkColour
        {
            get;
            set;
        }

        // Visual Studio might automatically update this path when you change the Visual Web Part project item.
        private const string _ascxPath = @"~/_CONTROLTEMPLATES/15/Your.Namespace/GenericPostWebpartUserControl.ascx";
        protected override void CreateChildControls()
        {
            GenericPostWebpartUserControl control = Page.LoadControl(_ascxPath) as GenericPostWebpartUserControl;
            if (control != null)
            {
                control.wp = this;
                control.wpContainerGUID = ClientID;
                control.siteurl = siteurl;
                control.listname = listname;
                control.postlimit = postlimit;
                control.category = category;
                control.linkColour = string.IsNullOrEmpty(linkColour) ? "#00ACB8" : linkColour;
                Controls.Add(control);
            }
        }
    }
}

Your elements XML file is next up, all you really need to do is set the group and title properties to what you want:

&lt;?xml version="1.0" encoding="utf-8"?>
&lt;Elements xmlns="http://schemas.microsoft.com/sharepoint/" >
  &lt;Module Name="GenericPostsWebpart" List="113" Url="_catalogs/wp">
    &lt;File Path="GenericPostsWebpart\GenericPostsWebpart.webpart" Url=" YournameSpace.WebParts_GenericPostsWebpart.webpart" Type="GhostableInLibrary">
      &lt;Property Name="Group" Value="Custom" />
      &lt;Property Name="Title" Value="Generic Posts" />
    &lt;/File>
  &lt;/Module>
&lt;/Elements>

The webpart file can be customised next, again the title and description are the parts your end users will see:

&lt;?xml version="1.0" encoding="utf-8"?>
&lt;webParts>
  &lt;webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
    &lt;metaData>
      &lt;type name="YournameSpace.WebParts.GenericPostsWebpart.GenericPostsWebpart, $SharePoint.Project.AssemblyFullName$" />
      &lt;importErrorMessage>$Resources:core,ImportErrorMessage;&lt;/importErrorMessage>
    &lt;/metaData>
    &lt;data>
      &lt;properties>
        &lt;property name="Title" type="string">GenericPostsWebPart&lt;/property>
        &lt;property name="Description" type="string">Displays blog type articles from any list&lt;/property>
      &lt;/properties>
    &lt;/data>
  &lt;/webPart>
&lt;/webParts>

This should get you a working web part that you can deploy to your test environment. What will it look like? What per-requisites is this web part expecting? First you’ll want a test site, with a subsite setup I’ve called mine ‘News’. This subsite was made ‘Blog’ template so it has a ‘Posts’ list already but you can just create one manually if you like.

Now on the parent site (not the ‘News’ subsite) add to any page your custom web part and configure it!

Site URL should be relative so something like /community/mysite/news

List name should be ‘Posts’ if you are using the out of the box Blog Site template otherwise point it at whatever custom list you created using that content type.

The post limit can be whatever you like 1 to 3 is usually good.

Category is actually just looking at the out of the box category column, use it to filter your news posts if you like. Works well with the colour coding.

Link colour is expecting a HEX colour code. Any HEX colour code will work.

What does this all result in? A neat little summary web part like so (text truncated):

The articles are clickable and open in a modal dialog, they provide all the social likes and comments functionality you get with the ‘Posts’ list and SharePoint 2013 and newer.

The modal dialogs contain the full article, the buttons show only if you have edit rights (these are custom and will be covered in another article):

At the bottom of each modal dialog your users can like and comment on these posts.

So there you have it, a simple re-usable generic posts web part. Use it however you will. The screenshots were done using a custom master page, the modal dialogs that open are also not the out of the box ones they’ve been customised too. I’ll hopefully write up all of that and how it works in the future.

A bird in a zoo in Athens, Greece! Enjoy.

Thanks for reading my blog posts, they are really just a way to capture what I do in day to day life.

October 11, 2019by Luke
Development, SharePoint

SharePoint Event Receiver Before and After Properties

When working with SharePoint lists and document libraries it’s easy to forget what properties exist when working with event receivers. This really only applies to those still writing on-premises C# code!

SharePoint List

ListBeforePropertiesAfterProperties properties.ListItem
ItemAddingNo ValueNew ValueNull
ItemAddedNo ValueNew ValueNew Value
ItemUpdatingNo ValueChanged ValueOriginal Value
ItemUpdatedNo ValueChanged ValueChanged Value
ItemDeletingNo ValueNo ValueOriginal Value
ItemDeletedNo ValueNo ValueNull

Lists are fairly straightforward with no before properties available.

SharePoint Document Library

LibraryBeforePropertiesAfterPropertiesproperties.ListItem
ItemAddingNo ValueNo ValueNull
ItemAddedNo ValueNo ValueNew Value
ItemUpdatingOriginal ValueChanged ValueOriginal Value
ItemUpdatedOriginal ValueChanged ValueChanged Value
ItemDeletingNo ValueNo ValueOriginal Value
ItemDeletedNo ValueNo ValueNull

Hopefully this is a useful reference to someone. I know I look this up quite often and I’m worried it will soon disappear off the face of the internet as the world forgets on-premises SharePoint.

July 5, 2019by Luke
Page 1 of 212»

Recent Posts

  • Mastering SharePoint Online REST APIs A Step-by-Step Guide
  • Building SharePoint Online Remote Event Receivers for Document Review Flows
  • Working with SharePoint Online REST Search API 101
  • Using the SPO Search REST API to create a Webpart showing Recently Modified Documents containing specific keywords
  • Creating a Custom SharePoint Online Webpart to Display Contact Details with Photos

Categories

  • Development
  • Latest
  • Patching
  • SharePoint
  • Testing
  • Tools

“I believe in doing what you enjoy, what drives you, what keeps you coming back for more. Code is life! Well it at least it pays the bills and lets me blog about it in my spare time!”

© 2019 copyright lukeosborne.dev // All rights reserved // Privacy Policy