Tuesday, September 19, 2017

Introducing a generic (mostly) all purpose extensibility schema for the Microsoft Graph

If you’ve followed my blog lately you know I’m experimenting with using Graph Extensions from the Microsoft Graph to persist metadata for resources in the graph, more specifically I’m storing metadata about different types of Office 365 Groups.

image

I decided to go with schema extensions over open extensions as this allows me to query and filter on my schema properties, instead of just reading and writing the properties. If you plan on only reading and writing data, I recommend using open extensions – why? Read on!

Wednesday, September 13, 2017

SharePoint Framework helper class for calling the Microsoft Graph

I’m creating a couple of web parts using SharePoint Framework in my current project so I figured I’d share a small helper class I created for performing GET requests against the Microsoft Graph. The code is written in TypeScript and handles single item results as well as paging on array results.

MSGraph.ts

import { GraphHttpClient, GraphHttpClientResponse } from '@microsoft/sp-http';

export class MSGraph {
    public static async Get(graphClient: GraphHttpClient, url: string) {
        let values: any[] = [];
        while (true) {
            let response: GraphHttpClientResponse = await graphClient.get(url, GraphHttpClient.configurations.v1);
            // Check that the request was successful
            if (response.ok) {
                let result = await response.json();
                let nextLink = result["@odata.nextLink"];
                // Check if result is single entity or an array of results
                if (result.value && result.value.length > 0) {
                    values.push.apply(values, result.value);
                }
                result.value = values;
                if (nextLink) {
                    url = result["@odata.nextLink"].replace("https://graph.microsoft.com/", "");
                } else {
                    return result;
                }
            }
            else {
                // Reject with the error message
                throw new Error(response.statusText);
            }
        }
    }
}

You can use the code as follows where I have extended the properties to include the web part context object in order to pass in graphHttpClient object.

import { MSGraph } from './MSGraph';

...

try {
  let groups = await MSGraph.Get(this.props.context.graphHttpClient, "v1.0/groups?$top=5");
} catch (error) {
  console.error(error);
}

Monday, September 11, 2017

An approach to working with Schema Extensions in the Microsoft Graph

I wrote a post last week about my issues with custom metadata and the Microsoft Graph. The week ended leaving me on the fence on which way to go. However, a couple of days off has sorted my brain a little bit, and I’ve had dialogs with the Graph team on these three Stack Overflow questions:

I think I’ve finally landed on using Schema Extensions and the approach below seems like something I can work with.

Friday, September 8, 2017

Making ESPC as easy as 1.2.3 – get 10% discount on checkout

Europe’s Largest SharePoint, Office 365 & Azure Conference is approaching fast. I’ll be presenting How to Take Control of Your Office 365 Groups – Using Technology to Solve Business Processes, a developer centric session on how you can control Groups creation and configuration using PowerApps, Flow, Azure Functions and PnP.

Here’s a few handy tips on how to make the most of your time at the conference.

Find out who’s going

Check out Twitter #ESPC17 to find out who’s going or visit the ESPC17 delegates page. If you would like to be added to this page, email your image and details to sarah@sharepointeurope.com There’s no better time to network with your peers, connect with new prospects, or touch base with customers than ESPC17. Don’t bank on running into them at the conference, reach out to them before and arrange a meeting.

Plan Ahead

Take a look at the conference schedule and decide the sessions and tutorials you would like to attend. Take note of their time so you can plan your meetings accordingly. If you are travelling with co-workers, split up and attend different sessions. You can swap notes after, allowing your company to get the most out of the conference.

Learn

Before the session, think of some questions you would like the answers to. Don’t be afraid to ask them during the Q&A, or alternatively go up and have a chat with the speaker afterwards. It is also important to take notes. A good practice is to write down the 3 most important takeaways from each session.

Socialize

With 2,000 people from the SharePoint, Office 365 & Azure community estimated to attend ESPC17, it is worth going to the after parties (The Black & White Party at the Guinness Storehouse on Wednesday 15th) and the many other great side-line and networking sessions, you never know who you’ll meet. Swap ideas, get advice and make those all-important contacts. Don’t be afraid to go up to a speaker or blogger and introduce yourself – they expect this at a conference.

Share what you learn

To capture maximum value for you and your company, schedule time to share what you’ve learned and even better, to go ahead and implement, as soon as you get back to the office. Organise an informal meeting with your colleagues and managers and share important takeaways from the conference.

image

Still haven’t made up your mind? Then visit 10 reasons to attend ESPC17 to see why you should be there. Then book your ticket today. Use coupon code ESPC17Speak on checkout to avail of a further 10% discount.

Thursday, September 7, 2017

Which schema to use in the Microsoft Graph for custom metadata: Schema Extensions or Open Extensions? Or maybe neither? I need help!

[Read my follow-up post at: http://www.techmikael.com/2017/09/an-approach-to-working-with-schema.html]

I’m trying to build out a solution for custom metadata for Office 365 Groups and it’s not that easy to do the right thing. My scenario is some worker process setting data, so I’m running in an app only context, not user delegated.

SNAGHTMLb983c97
If you don’t know what I’m talking about, Schema Extensions and Open Extensions are ways to store additional metadata to objects in the Microsoft Graph. Objects can for example be a user account, an e-mail message in Exchange or an Office 365 Group object. You persist the metadata with the object, not in some outside store.

Using Open Extensions is by far the easiest, as you can define your extension and the key/value pairs of data arbitrary, using the permissions of the object you are extending. The caveat however is that you cannot filter on these metadata. Say you added metadata to e-mail messages saying it’s customer related. Using Open Extension you cannot query to retrieve only those messages tagged. For me, not being able to filter is a blocker.

This is where Schema Extensions come in. Schema Extensions are typed schemas and you can indeed filter on them. But here are the issues I have experienced so far – I might be wrong about some of these, and base them off my testing. There is a whole lot more information about schema extensions on the old Azure AD Graph docs – which may or may not have solutions to my issues.
  • Schema Extensions cannot be created using app only permissions, so you cannot really automate it, and you might need a separate ADAL app to create it from the one you use for other automation.
  • A schema can not be used before it transitions from InDevelopment to Available.
  • You cannot delete a schema which has transitioned into being Available.
  • You cannot delete properties, only add new ones once a schema is made Available.
  • You cannot add a schema which is InDevelopment to for example an Office 365 Group object, making development harder.
  • Unless you have a verified domain of com, edu, net, org, you will end up with a random prefix for your schema extension. Which means you cannot easily filter to find the schema you created, but need to loop over all to find the one ending in your name. Unless you choose to record the name, but that won’t work for a generic solution across tenants.
In order to get the most flexible solution you might want to put metadata you need to filter on in a schema extension, and all others as open extension data. But this increases complexity as data are stored in two ways. Not the most ideal way to go, but a possibility.

Summary

While storing metadata in the Microsoft Graph seems like a good idea, as it reduces the number of moving parts, it might not be the best solution for every scenario. The ALM scenario for me right now is a bit in the wind, and perhaps storing the data outside the Microsoft Graph is a better and more flexible approach – even though I have to add more moving parts to the solution.

What’s your take?

Wednesday, August 30, 2017

How to update a SharePoint Framework project to Drop 1.2 (Extensions RC0)

[Update September 2nd, 2017]

I’ve updated the steps to remove the node_modules forlder, as that seems to fix some of the build libraries.

--

With the release of SharePoint Framework Extensions RC, SPFx has moved to Drop 1.2. If you want to update an existing project these are the steps you need to take.

Update the generator to Drop 1.2

npm install -g @microsoft/generator-sharepoint 

Enter your SPFx project folder and open package.json, where you need to update the version numbers for the following packages:

dependencies

"@microsoft/sp-core-library": "~1.2.0",
"@microsoft/sp-webpart-base": "~1.2.0",
"@types/react": "15.0.38",


devDependencies

"@microsoft/sp-build-web": "~1.2.0",
"@microsoft/sp-module-interfaces": "~1.2.0",
"@microsoft/sp-webpart-workbench": "~1.2.0"

If you have other @microsoft packages, set them to 1.2 as well, or if it’s @microsoft/sp-client-base, you can remove it.

Next up, remove your node_modules folder with your favorite command before running:

npm install
gulp --upgrade

And you should be all set!

NOTE! You may run into other breaking API changes you have to deal with.

NOTE 2! If you are using Office UI Fabric with react, Drop 1.2 takes a dependency on v4.32.0, and not on v2.34.2. If you have an explicit link to v2.x, then you have to upgrade in order for the build to work. See this issue for information about Office UI Fabric React which I raised with Drop 1.2 https://github.com/SharePoint/sp-dev-docs/issues/827

Sunday, August 27, 2017

Maybe the most useful Azure function ever! – Introducing a proper Swagger definition generator

This post relates to Azure functions written in C#, hosted as a Function App – and maybe the title is a tiny bit clickbaity ;)

I’m in a project where writing small Azure functions to accomplish pieces of functionality is a very good fit, and the tasks will be connected in a workflow – Microsoft Flow or Logic Apps. With the latest update for Visual Studio 2017, creating an Azure Function project and publish the function to Azure is super easy.

The tricky part comes when you want to consume those functions somewhere else using a Swagger definition file to describe your API.

The people over at the Azure team has been kind enough to add functionality to automatically generate a Swagger definition. The problem is that the output of this preview functionality is, to put it in nice terms, the equivalent to a table of contents, where the book was left out.

image

There are some blog posts out there on how you can write that book to get a working definition, but manual work when you have already defined the functions pretty well in code is not my cup of tea.

Digression

If an Azure function project had been a WebAPI or similar, you could have installed Swashbuckle, and you would have gotten a nice Swagger definition just like that. The fact that Azure functions are compiled to a class DLL, and that Swashbuckle does not work against a DLL in any easy fashion, I saw two options. A shadow API with Swashbuckle, or roll my own.

I started out with the first option where I created a shadow WebAPI project, copying all my Azure Function signatures, and then manually copying out parts to generate a proper Swagger definition. But I quickly discovered this was still too much manual work for my taste.

Option two it is – generate the mofo myself!

That left me with option two, write my own Swagger generator. The Swagger spec itself is not too complicated, and as Azure uses v2, that’s what I set to use as well. I’m no stranger to reflection on .Net DLL’s, having worked with SharePoint for many years, as well as writing other types of generators, so that’s what I did.

I created an Azure function in my project which at run time reflects on the current assembly, finds all methods marked to be Azure functions, then inspect their ins and outs, and construct a full fledged Swagger definition. To

It’s not complicated, but a bit tedious to support all the scenarios I wanted to support. I wanted to support input via the path, as query parameters and JSON objects in the body – which is the most useful one in my opinion. It took me one working day, 7.5h to have this up and ready to go, with ~400 lines of code. Imagine if the Azure team could have spend the same? But then again, I wouldn’t have this blog post :)

Thursday, August 24, 2017

SharePoint Query Tool moves to the PnP Tools repository and v2.7 released

As Codeplex is shutting down the repository for the SharePoint Query Tool has been moved over to the PnP Tools repo. I’m very happy about this move, and if you want to make changes or additions, feel free to make a PR.

Get v2.7 (link on the page)

The code was actually moved over in late May, but today I give you v2.7. There is one major new function, and one function removal.

Firstly, GQL support has been removed as Microsoft is removing support of this preview API.

Secondly I’ve had some requests about the login for SharePoint Online being tricky with cookies and multiple tenants, and lately those with single sign-on on their machines were force logged into their SSO domain.

In the connection dialog you can now choose SharePoint Online Management, which piggy backs on the way the SharePoint Online Management Shell authenticated.

This should give you an easy way to switch between tenants and accounts by re-clicking the sign-in button.

image

Monday, August 21, 2017

A workaround to support switching logins between tenants in Windows apps or PowerShell – Piggyback the Microsoft SharePoint Online Management Shell ADAL application

image

If you write Windows Applications or PowerShell scripts to connect to multiple tenants you have probably experienced the “That didn’t work” dialog where the web based login tries to log you in with some other tenant credential as cookies are persisted from an Internet Explorer or Edge session. This was a typical problem for the SharePoint Query Tool, and I managed to add some funky code to ensure cookies were ignored when the login window popped up.

However, recently I’ve had a couple of issues where people have domain/aad joined pc’s with single sign-on to Office 365. With this in place cookies doesn’t matter. The login dialog will always try to log you in with your current user when using IE/Edge, which happens to be the browser control available when programming in Windows. Hence, using the query tool was hard to use in these scenarios.

At the moment the Query Tool uses web browser login and a FedAuth cookie for authorization. The obvious workaround is to use an ADAL app and a Bearer token instead. This is quite easy to implement, but having people register a custom ADAL app per tenant to support this login flow seemed too cumbersome. And for those who know me, I always try to find an easy way out, and a clever work around came to mind.

Saturday, August 12, 2017

Dealing with package errors when building SharePoint Framework solutions

I’ve been working on a web part for a customer lately and was going to bundle it up and install it at the customers tenant. When I ran gulp --ship to prepare the bundle I got the following error:

[14:47:51] Error - [webpack] 'dist':
cylinder-configurator.bundle.js from UglifyJs
Unexpected token: name (finish) [cylinder-configurator.bundle.js:5976,6]

Something broke when the build process was running uglify-js. I opened by bundle in the temp\deploy folder and looked at line 5676. This was a reference to MathLab which was included my the npm package pica which I’m using in this project.

I figured as much as to solve my issue I needed to break pica out of the main build process, but how?

image

Again, my good friend Waldek pointed me in the right direction and he has actually written about this before, and the needed documentation can be found in the official SPFx documentation Add an external library to your SharePoint client-side web part.