diff --git a/samples/graph-rsc/csharp/M365Agent/aad.manifest.json b/samples/graph-rsc/csharp/M365Agent/aad.manifest.json
index 4032700262..9f95c1c21d 100644
--- a/samples/graph-rsc/csharp/M365Agent/aad.manifest.json
+++ b/samples/graph-rsc/csharp/M365Agent/aad.manifest.json
@@ -27,6 +27,10 @@
{
"id": "TeamsAppInstallation.ReadForUser.All",
"type": "Role"
+ },
+ {
+ "id": "TeamsActivity.Send",
+ "type": "Role"
}
]
}
diff --git a/samples/graph-rsc/csharp/M365Agent/env/.env.local b/samples/graph-rsc/csharp/M365Agent/env/.env.local
index 86528dae75..4c8dfbb316 100644
--- a/samples/graph-rsc/csharp/M365Agent/env/.env.local
+++ b/samples/graph-rsc/csharp/M365Agent/env/.env.local
@@ -4,18 +4,3 @@
TEAMSFX_ENV=local
# Generated during provision, you can also add your own variables.
-TEAMS_APP_ID=
-AAD_APP_CLIENT_ID=
-AAD_APP_OBJECT_ID=
-AAD_APP_OAUTH2_PERMISSION_ID=
-AAD_APP_TENANT_ID=
-AAD_APP_OAUTH_AUTHORITY_HOST=
-AAD_APP_OAUTH_AUTHORITY=
-TAB_ENDPOINT=
-
-TEAMSFX_M365_USER_NAME=
-
-APP_NAME_SUFFIX=
-TAB_DOMAIN=
-TEAMS_APP_TENANT_ID=
-AAD_APP_ACCESS_AS_USER_PERMISSION_ID=
\ No newline at end of file
diff --git a/samples/graph-rsc/csharp/M365Agent/m365agents.yml b/samples/graph-rsc/csharp/M365Agent/m365agents.yml
index 91b0d44a13..424749fb39 100644
--- a/samples/graph-rsc/csharp/M365Agent/m365agents.yml
+++ b/samples/graph-rsc/csharp/M365Agent/m365agents.yml
@@ -6,4 +6,5 @@ version: v1.2
additionalMetadata:
sampleTag: Microsoft-Teams-Samples:graph-rsc-csharp
-environmentFolderPath: ./env
\ No newline at end of file
+environmentFolderPath: ./env
+projectId:
diff --git a/samples/graph-rsc/csharp/README.md b/samples/graph-rsc/csharp/README.md
index 4a6535f35b..2b2f43960a 100644
--- a/samples/graph-rsc/csharp/README.md
+++ b/samples/graph-rsc/csharp/README.md
@@ -78,7 +78,9 @@ The simplest way to run this sample in Teams is to use Teams Toolkit for Visual
1) Register your app with Microsoft identity platform via the Microsoft Entra ID portal (Microsoft Entra ID app registration)
- Your app must be registered in the Microsoft Entra ID portal to integrate with the Microsoft identity platform and call Microsoft Graph APIs. See [Register an application with the Microsoft identity platform](https://docs.microsoft.com/graph/auth-register-app-v2).
-**Note** - Make sure you have added `TeamsAppInstallation.ReadForUser.All` as Application level
+**Note** - Make sure you have added below permissions
+1. `TeamsAppInstallation.ReadForUser.All` as Application level
+2. `TeamsActivity.Send` as Application level
2) Clone the repository
```bash
diff --git a/samples/graph-rsc/csharp/RSCDemo/Controllers/HomeController.cs b/samples/graph-rsc/csharp/RSCDemo/Controllers/HomeController.cs
index dae35a971e..c0bc3f33ac 100644
--- a/samples/graph-rsc/csharp/RSCDemo/Controllers/HomeController.cs
+++ b/samples/graph-rsc/csharp/RSCDemo/Controllers/HomeController.cs
@@ -1,4 +1,10 @@
-using Microsoft.AspNetCore.Mvc;
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+
+using Azure.Core;
+using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Graph;
using Microsoft.Identity.Client;
@@ -13,13 +19,13 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using static RSCDemo.Helper.GraphClient;
namespace RSCWithGraphAPI.Controllers
{
public class HomeController : Controller
{
private readonly IConfiguration _configuration;
-
public string appId;
public HomeController(IConfiguration configuration)
@@ -79,9 +85,24 @@ private async Task> GetPermissionGrants(GraphServiceClient graphCli
return result.Value.Select(r => r.Permission).ToList();
}
+ ///
+ /// Get Authenticated Graph Client (fixed for Graph SDK 5+)
+ ///
+ private async Task GetAuthenticatedClient()
+ {
+ var accessToken = await GetToken();
+
+ var accessTokenProvider = new SimpleAccessTokenProvider(accessToken);
+
+ var authProvider = new BaseBearerTokenAuthenticationProvider(accessTokenProvider);
+
+ var graphClient = new GraphServiceClient(authProvider);
+
+ return graphClient;
+ }
///
- ///Get Authenticated Client
+ /// Simple Access Token Provider for Graph SDK
///
public class SimpleAccessTokenProvider : IAccessTokenProvider
{
@@ -92,21 +113,33 @@ public SimpleAccessTokenProvider(string accessToken)
_accessToken = accessToken;
}
- public Task GetAuthorizationTokenAsync(Uri uri, Dictionary context = null, CancellationToken cancellationToken = default)
+ public AllowedHostsValidator AllowedHostsValidator { get; }
+
+ public async Task GetAuthorizationTokenAsync(Uri uri, Dictionary additionalAuthenticationContext = null, CancellationToken cancellationToken = default)
{
- return Task.FromResult(_accessToken);
+ return _accessToken;
}
-
- public AllowedHostsValidator AllowedHostsValidator => new AllowedHostsValidator();
}
- private async Task GetAuthenticatedClient()
+ // New helper class to return AccessToken
+ private class SimpleAccessTokenCredential : TokenCredential
{
- var accessToken = await GetToken();
- var tokenProvider = new SimpleAccessTokenProvider(accessToken);
- var authProvider = new BaseBearerTokenAuthenticationProvider(tokenProvider);
+ private readonly string _accessToken;
+
+ public SimpleAccessTokenCredential(string accessToken)
+ {
+ _accessToken = accessToken;
+ }
+
+ public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken)
+ {
+ return new AccessToken(_accessToken, DateTimeOffset.UtcNow.AddHours(1));
+ }
- return new GraphServiceClient(authProvider);
+ public override ValueTask GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)
+ {
+ return new ValueTask(new AccessToken(_accessToken, DateTimeOffset.UtcNow.AddHours(1)));
+ }
}
///
@@ -142,19 +175,18 @@ public async Task GetInstalledAppList(string reciepientUserId)
{
// Read and display the response content
string responseBody = await response.Content.ReadAsStringAsync();
-
var responseData = JsonConvert.DeserializeObject(responseBody);
var installedAppList = responseData.Value;
- foreach(AppData element in installedAppList)
+ foreach (AppData element in installedAppList)
{
if (element.TeamsAppDefinition.DisplayName == "RSC-GraphAPI ")
{
appId = element.Id;
}
- };
+ }
- if(appId != null)
+ if (appId != null)
{
await SendNotification(reciepientUserId, appId);
return Json("Message sent successfully");
@@ -167,13 +199,13 @@ public async Task GetInstalledAppList(string reciepientUserId)
else
{
Console.WriteLine($"Error: {response.StatusCode}");
- return Json("Error occured");
+ return Json("Error occurred");
}
}
catch (Exception ex)
- {
+ {
Console.WriteLine($"Error: {ex.Message}");
- return Json("Error occured"+ ex.Message);
+ return Json("Error occurred: " + ex.Message);
}
}
}
@@ -230,7 +262,7 @@ public async Task SendNotification(string reciepientUserId, string appId
else
{
Console.WriteLine($"Error: {response.StatusCode}");
- return "Notification sent";
+ return "Notification failed";
}
}
catch (Exception ex)
diff --git a/samples/graph-rsc/csharp/RSCDemo/Helper/GraphClient.cs b/samples/graph-rsc/csharp/RSCDemo/Helper/GraphClient.cs
new file mode 100644
index 0000000000..2c951864e0
--- /dev/null
+++ b/samples/graph-rsc/csharp/RSCDemo/Helper/GraphClient.cs
@@ -0,0 +1,44 @@
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+
+using Microsoft.Graph;
+using Microsoft.Kiota.Abstractions.Authentication;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Threading;
+using System;
+
+namespace RSCDemo.Helper
+{
+ public class GraphClient
+ {
+
+ public class SimpleAccessTokenProvider : IAccessTokenProvider
+ {
+ private readonly string _accessToken;
+
+ public SimpleAccessTokenProvider(string accessToken)
+ {
+ _accessToken = accessToken;
+ }
+
+ public Task GetAuthorizationTokenAsync(Uri uri, Dictionary context = null, CancellationToken cancellationToken = default)
+ {
+ return Task.FromResult(_accessToken);
+ }
+
+ public AllowedHostsValidator AllowedHostsValidator => new AllowedHostsValidator();
+ }
+
+ public static GraphServiceClient GetGraphClient(string accessToken)
+ {
+ var tokenProvider = new SimpleAccessTokenProvider(accessToken);
+ var authProvider = new BaseBearerTokenAuthenticationProvider(tokenProvider);
+
+ return new GraphServiceClient(authProvider);
+ }
+
+ }
+}
diff --git a/samples/graph-rsc/csharp/RSCDemo/Models/DemoViewModel.cs b/samples/graph-rsc/csharp/RSCDemo/Models/DemoViewModel.cs
index 1956c664d6..959c4d3fe7 100644
--- a/samples/graph-rsc/csharp/RSCDemo/Models/DemoViewModel.cs
+++ b/samples/graph-rsc/csharp/RSCDemo/Models/DemoViewModel.cs
@@ -1,8 +1,9 @@
-using Microsoft.Graph;
-using System;
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+
using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
namespace RSCWithGraphAPI.Models
{
diff --git a/samples/graph-rsc/csharp/RSCDemo/Models/ErrorViewModel.cs b/samples/graph-rsc/csharp/RSCDemo/Models/ErrorViewModel.cs
index e132ca4830..be04ea5c4c 100644
--- a/samples/graph-rsc/csharp/RSCDemo/Models/ErrorViewModel.cs
+++ b/samples/graph-rsc/csharp/RSCDemo/Models/ErrorViewModel.cs
@@ -1,4 +1,7 @@
-using System;
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
namespace RSCWithGraphAPI.Models
{
diff --git a/samples/graph-rsc/csharp/RSCDemo/Models/ResponseData.cs b/samples/graph-rsc/csharp/RSCDemo/Models/ResponseData.cs
index 95e1aad0b6..806dcd18c9 100644
--- a/samples/graph-rsc/csharp/RSCDemo/Models/ResponseData.cs
+++ b/samples/graph-rsc/csharp/RSCDemo/Models/ResponseData.cs
@@ -1,4 +1,9 @@
-using System.Collections.Generic;
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+
+using System.Collections.Generic;
namespace RSCWithGraphAPI.Models
{
diff --git a/samples/graph-rsc/csharp/RSCDemo/appsettings.json b/samples/graph-rsc/csharp/RSCDemo/appsettings.json
index 05047e9db8..9494e61379 100644
--- a/samples/graph-rsc/csharp/RSCDemo/appsettings.json
+++ b/samples/graph-rsc/csharp/RSCDemo/appsettings.json
@@ -1,13 +1,13 @@
{
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
- }
- },
- "AllowedHosts": "*",
- "ClientId": "<>",
- "ClientSecret": "<>",
- "TenantId": "<>"
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "AllowedHosts": "*",
+ "ClientId": "",
+ "ClientSecret": "",
+ "TenantId": ""
}
\ No newline at end of file