Article
0 comment

Use Microsoft Graph to evaluate SharePoint Urls

Recently I added a new sample to the PNP SharePoint Framework examples. The goal of this sample was to take text field input evaluate it against the Microsoft Graph and get information back information about a site collection, websites and list or libraries.

This blog post is no in-depth article on how to query the Microsoft Graph or how to make the code to work and authentication works. If you need to install microsoft visit https://softwaredepot.co/download-microsoft-office.html. Instead, I like to give you an overview of the ideas behind the implementations.

Text Input – Can be difficult

If you love your end user, you make sure you only have a less as possible drop downs. If you need to store for example a URL to a website or library in an Office 365 web part, it is way better to save the actually URL.

You can implement a cascading dropdown that lists websites and based on the first selection you can then choose a list. Nice user experience right? Well not so much. In case you like to open the resulting URL you have to implement a button that is label as “Test this URL” combine the values of the two dropdowns and open a new browser tab.

Why not store the URL directly and allow the user to input an URL that he might have already open in one of his tabs.

Then you have a less structured way to save your settings but still have a text value to evaluate which sometimes can be tricky and especially in SharePoint.

URL WebApi – to evaluate an URL

If you created substrings to assess a URL input and checked for protocols and path base on the defined semantic, then you add a lot of code to your solution. Code that is not needed anymore because there is a WebAPI already have a solution for this kind of evaluation.

var parsedUrl = new URL('https://contonso.sharepoint.com/Shared Documents/')
console.log(parsedUrl.hostname) // <- returns 'contoso.sharepoint.com'
console.log(parsedUrl.path) // <- returns '/Shared Documents/

This URLobject directly takes a string input and evaluate and parse it. If this parsing succeeds you can request things like the hostname or the path; if this fails you get a pleasant exception that you can catch in your code.

One word of warning. Most modern browsers and even Microsoft Edge support this object. In case of Internet Explorer, you need to use a polyfill.

Where am I in SharePoint

Now with a proper passed URL, we are up to identify the path in SharePoint. In Office 365 there are two options to evaluate.

https://contoso.sharepoint.com/Shared Documents/

Because of the missing ‘/sites/’ in the path we can be sure that this points to the root site collection. The other option is when we have an URL like the following.

https://contoso.sharepoint.com/sites/sales/Shared Documents/

This ‘/sites/’ indicates that we might like to identify a site collection or web apart of the root site collection. The question in which website try to target.

There is still a small problem to solve. Does ‘Shared Documents’ points to a subweb or a list or library? The compromise I made was to remove the last piece of the URL path. In other words, I removed ‘Shared Documents’.

In case of dealing with lists, they are much easier to evaluate, because we need to check only for the existence of ‘/lists/’ in the path.

https://contoso.sharepoint.com/sites/sales/internal/lists/mycustomlist/

The URL provided above for example points to a list.

Another check required is what if the user enters the following URL in the text field.

https://contoso.sharepoint.com/sites/sales/Shared%20Documents/Forms/AllItems.aspx

The ‘.aspx’ indicates that this points to a view or a site page maybe. The existence of ‘/forms/’ identify this URL as a view of a document library for example.

The check for lists was already covered previously and the

‘.aspx’ then points to a view, new, edit or display form.

I know that all these checks are more an assumption based on the URL structure semantics in SharePoint. It is not 100% perfect but close.

Query and evaluate against the Microsoft Graph

With AJAX my golden rule is that the best AJAX queries are those I don’t have to make. It means that I try to avoid those I can address differently and reduces the overall impact.

Let’s take a look how we can evaluate a site collection first.

Evaluate site collection

Like I mentioned before there are only two options to get the site collection from the Microsoft Graph. When the URL doesn’t include ‘/sites/’, I know that the path points somewhere in the root site collection. Otherwise, I need to query a subsite collection.

Get root site collection:

https://graph.microsoft.com/v1.0/sites/root/

This query returns the root site collection. Subsite collection needs to be requested differently.

Get sub site collection

https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/news/

It is essential that you pass in your SharePoint hostname followed by a colon and followed by the server relative URL of the subsite collection.

Evaluate webs inside root site collection

Evaluate a web in Microsoft Graph apart from a site collection is tricky. Here is the reason why. Let’s assume we are in the root site collection and a subweb with the following path exists.

https://conosoto.sharepoint.com/Customers

To query the graph according to the documentation you tend to use the following graph query.

https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/Customer

The query results in a ‘BadRequest’ because of a request to a subweb in the root site collection cannot be accessed through the server relative URL and the hostname.

https://graph.microsoft.com/v1.0/sites/root/Customer

This time the result is different, but the result is also ‘BadRequest’. The only way to evaluate subsites is to get the enumeration of all subsites with the following query.

https://graph.microsoft.com/v1.0/sites/root/sites

Now you get a list of all subsites returned and can make a lookup for a matching ‘webUrl’ property. You should be aware that right now all ‘webUrl’ get returned without an ending slash. So you have to remove the last one from the path.

Evaluate web in subsite collection

To evaluate a subweb in a site collection other than root that is relatively simple. You need to use the following query.

https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/sales/Customer

So for all other webs outside of the root site collection, all you need is to pass in the hostname followed by a colon and the relative server URL. After that, you can directly evaluate lists and document libraries.

Evaluate List or Document Library

To request the site collection or web first crucial for any further evaluation. The result returned contains an id that we need to pass into the list and document evaluation. The query pattern in the documentation loos like this.

Request all all list https://graph.microsoft.com/v1.0/sites/{site-id}/lists

https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com,5a58bb09-1fba-41c1-8125-69da264370a0,7268dd48-720e-4115-a352-35db188918be/lists

This query returns an array of all lists in a specified web. The last setup is to filter out a matching URL to the given URL.

About the sample

The complete sample is currently available in the dev branch of sp-dev-fx-webparts. With some luck, it should be in the master branch soon.

I isolated the class GraphEvalClient entirely from the user interface to make sure it is reusable in other projects too.

The user interface is built using React, but this is not a must because there are no React specifics in the client. This class can even be used to evaluate inputs in the property pane.

If you like to take a closer look at my solution, you will find the source code of the GraphEvalClient on GitHub.

Leave a Reply

Required fields are marked *.


This site uses Akismet to reduce spam. Learn how your comment data is processed.