Exercise - Configure an external connection and deploy schema
In this exercise, you build a custom Microsoft Graph connector as a console application. You register a new Microsoft Entra app registration and add the code to create an external connection and deploy its schema.
Create a new Graph connector project
Start, by creating a new Graph connector project. While you could create the project and all necessary files manually, in this example you use the template GitHub repository for Graph connectors. The benefit of using the template repository is that it creates a simple project for you with the necessary files and dependencies, saving you time.
In a command line:
Clone the template repository by running
git clone https://github.com/microsoft/learn-microsoft-graph-connectors-dotnet.git
Tip
If you don't have git installed or you don't have a GitHub account, you can download the repository as a ZIP file. Extract the ZIP file to a folder on your computer to continue with the exercise.
Change the working directory to the cloned repository.
Open the newly created project in your code editor.
In the code editor:
- Open the ConnectionConfiguration.cs file. In the object returned by the
ExternalConnection
getter:- Change the value of the Id property to
msgraphdocs
. - Change the value of the Name property to
Microsoft Graph documentation
. - Change the value of the Description property to
Documentation for Microsoft Graph API which explains what Microsoft Graph is and how to use it
.
- Change the value of the Id property to
- Save your changes.
Tip
The README.md
file in the generated project contains more information about the different files and folders in the project. Take a moment to read it and familiarize yourself with the project structure.
Register a new Microsoft Entra app registration
The project you created contains a setup script that creates and configures a new Microsoft Entra app registration. The Graph connector uses this app registration to authenticate with Microsoft 365.
In a command line:
- Change the working directory to the project folder.
- Run the setup script:
.\setup.ps1
- When prompted, sign in to your Microsoft 365 tenant with your work account.
- Wait for the script to finish creating the app registration. The script creates an Entra app registration named Microsoft Graph documentation.
- When the script finishes, it securely stores the app registration information in user secrets.
The setup script uses the Microsoft Graph PowerShell SDK to create a new Microsoft Entra app registration in your tenant. It configures the app registration with Microsoft Graph API permissions required to create an external connection and ingest content. It also configures the app registration with a secret to allow authenticating without user interaction.
Tip
To explore the app registration configuration, in a web browser:
- Go to the Azure Portal at https://portal.azure.com.
- From the navigation, select Microsoft Entra ID.
- From the side navigation, select App registrations.
- From the list of app registrations, select the app registration created by the setup script.
- Explore the different properties, such as API permissions, Certificates & secrets, and Authentication.
Define external connection and schema configuration
The next step is to define the external connection and schema that the Graph connector should use. Because the connector's code needs access to the external connection's ID in several places, store it in a central place in your code.
In the code editor:
Open the ConnectionConfiguration.cs file.
From the object returned by the
ExternalConnection
property, remove theActivitySettings
andSearchSettings
properties. You don't need them for this exercise.Notice the schema properties returned by the
Schema
property.The first property is
title
, which stores the title of the external item imported to Microsoft 365. The item's title is a part of the full-text index (IsSearchable = true
). Users can also explicitly query for its contents in keyword queries (IsQueryable = true
). The title can be also retrieved and displayed in search results (IsRetrievable = true
). Thetitle
property represents the item's title, which you indicate using theTitle
semantic label.Next, there's the
url
property, which stores the original URL of the external item. Users use this URL to navigate to the external item from search results or Copilot from Microsoft 365. URL is one of the properties that Microsoft 365 Copilot requires, which is why you map it using theUrl
semantic label.Finally, there's the
iconUrl
property that stores the URL of the icon for each item. Microsoft 365 Copilot requires this property and it needs to be mapped using theIconUrl
semantic label.Microsoft 365 Copilot requires Graph connectors to define at least these three properties and designate them with the appropriate semantic labels.
To the
Properties
array, add a new property nameddescription
:new Property { Name = "description", Type = PropertyType.String, IsQueryable = true, IsSearchable = true, IsRetrievable = true }
The
description
property stores the summary of the contents of the external item. Its definition is similar to the title. There's however no semantic label for the description, which is why you don't define it.The complete code looks as follows:
using System.Text.Json; using Microsoft.Graph.Models; using Microsoft.Graph.Models.ExternalConnectors; static class ConnectionConfiguration { private static Dictionary<string, object>? _layout; private static Dictionary<string, object> Layout { get { if (_layout is null) { var adaptiveCard = File.ReadAllText("resultLayout.json"); _layout = JsonSerializer.Deserialize<Dictionary<string, object>>(adaptiveCard); } return _layout!; } } public static ExternalConnection ExternalConnection { get { return new ExternalConnection { Id = "msgraphdocs", Name = "Microsoft Graph documentation", Description = "Documentation for Microsoft Graph API which explains what Microsoft Graph is and how to use it." }; } } public static Schema Schema { get { return new Schema { BaseType = "microsoft.graph.externalItem", Properties = new() { new Property { Name = "title", Type = PropertyType.String, IsQueryable = true, IsSearchable = true, IsRetrievable = true, Labels = new() { Label.Title } }, new Property { Name = "url", Type = PropertyType.String, IsRetrievable = true, Labels = new() { Label.Url } }, new Property { Name = "iconUrl", Type = PropertyType.String, IsRetrievable = true, Labels = new() { Label.IconUrl } }, new Property { Name = "description", Type = PropertyType.String, IsQueryable = true, IsSearchable = true, IsRetrievable = true } } }; } } }
Save your changes
Review connection creation code
The Graph connector project generator creates code that creates the external connection and provisions its schema. You can use it without any changes. Before you do, have a look at it to understand how it works. The code is in the ConnectionService.cs file.
In the code editor:
- Open the ConnectionService.cs file.
- The file contains two methods:
CreateConnection
andCreateSchema
. TheCreateConnection
method creates the external connection, and theCreateSchema
method provisions the schema.
If you recall, provisioning external connection schema is a long-running operation. The code in the CreateSchema
method however doesn't seem to be waiting for the schema to be provisioned. The Microsoft Graph client in this project uses a custom middleware that waits for the operation to complete. Because this middleware handles waiting for the operation to complete, the CreateSchema
function doesn't need to include any other code and only needs to await the API request. The middleware is in the CompleteJobWithDelayHandler.cs file.
Test the code
The last step left is to verify that the code is working correctly. The Program.cs file contains the entry point for the application. It uses the System.CommandLine package to define a command that you invoke by starting the application from the command line.
In a command line:
- Open a terminal.
- Change the working directory to the project folder.
- Run
dotnet build
to build the project. - Start the app by running
dotnet run -- create-connection
. - Wait several minutes for the connection and schema to be created.