What is Microsoft Graph API?
Microsoft Graph API is a comprehensive set of RESTful web APIs provided by Microsoft to enable developers to access and interact with a wide range of Microsoft 365 services. Microsoft 365, formerly known as Office 365, includes services such as Microsoft Outlook, OneDrive, SharePoint, Microsoft Teams, and more.
Microsoft Graph API allows developers to build applications that can access data and perform various tasks across different Microsoft 365 services using a single endpoint. It provides a unified programming model that simplifies the development process by offering a consistent way to interact with diverse Microsoft 365 data and services.
Key features and capabilities of Microsoft Graph API
- Unified Endpoint: Developers can use a single API endpoint (https://graph.microsoft.com) to access data and resources across multiple Microsoft 365 services.
- Authentication: Microsoft Graph API uses OAuth 2.0 for authentication, ensuring secure access to user and organizational data.
- Rich Data Access: It provides access to a wide range of data, including user profiles, emails, calendar events, files, and more.
- Webhooks and Change Notifications: Developers can subscribe to changes in data and receive real-time notifications, allowing for more efficient and responsive applications.
- Consistent Query Language: Microsoft Graph API uses the OData query language, making it easy for developers to retrieve and filter data based on specific criteria.
- Application Integration: Developers can integrate Microsoft Graph API into their applications, whether they are web, mobile, desktop, or server applications.
- Open Standards: Microsoft Graph API follows open standards, facilitating interoperability and integration with various platforms and technologies.
Developers can use Microsoft Graph API to create a wide range of applications, from productivity tools and workflow automation to business intelligence and analytics solutions. It provides a powerful way to leverage the capabilities of Microsoft 365 in custom applications and services.
Graph API Explore: https://developer.microsoft.com/en-us/graph/graph-explorer
How can I get started
To get started with Microsoft Graph API in C#, you can follow these steps.
- Set Up a Microsoft 365 Developer Account: If you don't have one, create a Microsoft 365 developer account. This will provide you access to the Microsoft 365 Developer Program, which includes a subscription with development resources.
- Register Your Application
- Go to the Microsoft Azure Portal.
- Navigate to the "Azure Active Directory" section.
- Register a new application to obtain the client ID and client secret.
- Configure API Permissions: In the registered application, configure the required API permissions, such as Calendars.Read for accessing calendar data or User.Read for reading user data.
- Acquire Access Token: In your C# application, use OAuth 2.0 to obtain an access token. You will need the client ID, client secret, and the appropriate endpoint.
Example
Required Packages
From NuGet
Install-Package Azure.Identity -Version 1.10.4
Install-Package Microsoft.Graph -Version 5.40.0
Create an interface for Graph Service Client.
public interface IMSGraphServiceClient
{
GraphServiceClient GraphServiceClient { get; }
}
Then, Implement the Interface in the class as follows.
public class MSGraphServiceClient : IMSGraphServiceClient
{
public GraphServiceClient GraphServiceClient { get; }
public MSGraphServiceClient(string TenantId, string ClientId, string ClientSecret)
{
var options = new TokenCredentialOptions { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud };
var clientCred = new ClientSecretCredential(tenantId: TenantId, clientId: ClientId, clientSecret: ClientSecret, options);
var scopes = new[] { "https://graph.microsoft.com/.default" };
GraphServiceClient = new GraphServiceClient(clientCred, scopes);
}
}
Create two interfaces for accessing Event and User Details from Graph Service.
public interface IMSGraphEventAccess
{
/// <summary>
/// CreateEventAsync -> Create a calendar event based on the data
/// </summary>
/// <param name="OrganizerEmail">Who creates an event</param>
/// <param name="dataForPost">Event Data</param>
/// <returns></returns>
Task<Event> CreateEventAsync(string OrganizerEmail, Event dataForPost);
/// <summary>
/// CancelEventAsync -> Cancel an event by ID
/// </summary>
/// <param name="OrganizerEmail"></param>
/// <param name="EventId">Event ID</param>
/// <returns></returns>
Task CancelEventAsync(string OrganizerEmail, string EventId);
/// <summary>
/// GetEventAsync -> Get an event by ID
/// </summary>
/// <param name="OrganizerEmail"></param>
/// <param name="EventId"></param>
/// <returns></returns>
Task<Event> GetEventAsync(string OrganizerEmail, string EventId);
/// <summary>
/// UpdateEventAsync -> Update an event by event data
/// </summary>
/// <param name="OrganizerEmail">Who created an event</param>
/// <param name="dataForPost">Data</param>
/// <returns></returns>
Task<Event> UpdateEventAsync(string OrganizerEmail, Event dataForPost);
}
public interface IMSGraphUserAccess
{
/// <summary>
/// Gettting User Details by mail
/// </summary>
/// <param name="UserEmail"></param>
/// <returns></returns>
Task<User> GetUserDetailsAsync(string UserEmail);
}
The class implementation is as follows.
public class GraphUserAPIAccessor : IMSGraphUserAccess
{
private readonly GraphServiceClient _graphServiceClient;
public GraphUserAPIAccessor(IMSGraphServiceClient graphServiceClient)
{
_graphServiceClient = graphServiceClient.GraphServiceClient;
}
/// <summary>
/// Get User Details by mail
/// </summary>
/// <param name="UserEmail"></param>
/// <returns></returns>
public async Task<User> GetUserDetailsAsync(string UserEmail) =>
await _graphServiceClient.Users[UserEmail].GetAsync() ?? new User();
}
public class GraphEventAPIAccessor : IMSGraphEventAccess
{
private readonly GraphServiceClient _graphServiceClient;
public GraphEventAPIAccessor(IMSGraphServiceClient graphServiceClient)
{
_graphServiceClient = graphServiceClient.GraphServiceClient;
}
/// <summary>
/// CreateEventAsync -> Create a calendar event based on the data
/// </summary>
/// <param name="OrganizerEmail">Who creates an event</param>
/// <param name="dataForPost">Event Data</param>
/// <returns></returns>
public async Task<Event> CreateEventAsync(string OrganizerEmail, Event dataForPost) =>
await _graphServiceClient.Users[OrganizerEmail].Calendar.Events.PostAsync(dataForPost) ?? new Event();
/// <summary>
/// CancelEventAsync -> Cancel an event by ID
/// </summary>
/// <param name="OrganizerEmail"></param>
/// <param name="EventId">Event ID</param>
/// <returns></returns>
public async Task CancelEventAsync(string OrganizerEmail, string EventId)
{
try
{
var eventGet = await _graphServiceClient.Users[OrganizerEmail].Calendar.Events[EventId].GetAsync();
if (eventGet != null)
{
await _graphServiceClient.Users[OrganizerEmail].Calendar.Events[EventId].DeleteAsync();
}
else
{
throw new Exception("No Event Found");
}
}
catch
{
throw;
}
}
/// <summary>
/// UpdateEventAsync -> Update an event by event data
/// </summary>
/// <param name="OrganizerEmail">Who created an event</param>
/// <param name="dataForPost">Data</param>
/// <returns></returns>
public async Task<Event> UpdateEventAsync(string OrganizerEmail, Event dataForPost)
{
try
{
var eventGet = await _graphServiceClient.Users[OrganizerEmail].Calendar.Events[dataForPost.Id].GetAsync();
if (eventGet != null)
{
return await _graphServiceClient.Users[OrganizerEmail].Calendar.Events[dataForPost.Id].PatchAsync(dataForPost) ?? new Event();
}
else
{
throw new Exception("No Event Found");
}
}
catch
{
throw;
}
}
public async Task<Event> GetEventAsync(string OrganizerEmail, string EventId) =>
await _graphServiceClient.Users[OrganizerEmail].Calendar.Events[EventId].GetAsync() ?? new Event();
}
Inject the details at the startup of the Service.
// TODO Read from Configurations
builder.Services.AddSingleton<IMSGraphServiceClient>(x => new MSGraphServiceClient(
TenantId: "",
ClientId: "",
ClientSecret: ""
));
builder.Services.AddScoped<IMSGraphUserAccess, GraphUserAPIAccessor>();
builder.Services.AddScoped<IMSGraphEventAccess, GraphEventAPIAccessor>();
Implementation and Access of the resources (User Details and Event - Calendar Meetings).
public class HomeController(ILogger<HomeController> logger, IMSGraphEventAccess mSGraphEventAccess, IMSGraphUserAccess mSGraphUser) : Controller
{
private readonly ILogger<HomeController> _logger = logger;
private readonly IMSGraphEventAccess _mSGraphEventAccess = mSGraphEventAccess;
private readonly IMSGraphUserAccess _mSGraphUser = mSGraphUser;
public async void MSGraphAPIAccessingEvent()
{
Event testing = new()
{
Attendees =[
new() { EmailAddress = new EmailAddress() { Address = "[email protected]", Name = "User 1" } },
new() { EmailAddress = new EmailAddress() { Address = "[email protected]", Name = "User 2" } }
],
Body = new ItemBody() { Content = "Testing Meeting Updated Content <b> Welcome </b>" },
CreatedDateTime = DateTime.Now,
End = new DateTimeTimeZone() { DateTime = DateTime.Now.AddDays(1).AddHours(4).ToString("yyyy-MM-dd hh:mm:ss"), TimeZone = TimeZoneInfo.Local.StandardName },
Start = new DateTimeTimeZone() { DateTime = DateTime.Now.AddDays(1).AddHours(2).ToString("yyyy-MM-dd hh:mm:ss"), TimeZone = TimeZoneInfo.Local.StandardName },
Location = new Location() { DisplayName = "Office Conf Room #344 A" },
Subject = "Testing Meeting Updated Content",
Categories = ["Interview"]
};
try
{
string orgnUser = "[email protected]";
var details =await _mSGraphUser.GetUserDetailsAsync(orgnUser);
var createdEvent = await _mSGraphEventAccess.CreateEventAsync(orgnUser, testing);
var eventGet = await _mSGraphEventAccess.GetEventAsync(orgnUser, createdEvent.Id ?? "");
if (eventGet != null)
{
eventGet.Location = new Location() { DisplayName = "Office Conf Room #342 B" };
var updatedEvent = await _mSGraphEventAccess.UpdateEventAsync(orgnUser, eventGet);
await _mSGraphEventAccess.CancelEventAsync(orgnUser, updatedEvent.Id ?? "");
}
}
catch (Exception exp)
{
_logger.LogCritical(exp.Message);
}
}
}
That's all. We will see in detail about the Single Sign On of Microsoft in the Next Article.