Skip to content

Commit 6b150dc

Browse files
author
Tiago Brenck
authored
Merge pull request #238 from Azure-Samples/tibre/236
Issue 236 - Update readme to show graph SDK classes
2 parents 4a7e3a6 + e361dd7 commit 6b150dc

File tree

1 file changed

+86
-60
lines changed
  • 2-WebApp-graph-user/2-1-Call-MSGraph

1 file changed

+86
-60
lines changed

2-WebApp-graph-user/2-1-Call-MSGraph/README.md

Lines changed: 86 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,9 @@ The two new lines of code:
150150

151151
### Add additional files to call Microsoft Graph
152152

153-
Add the `Services\Microsoft-Graph-Rest\*.cs` files. This is an implementation of a custom service which encapsulates the call to the Microsoft Graph /me endpoint. Given an access token for Microsoft Graph, it's capable of getting the user information and the photo of the user.
153+
Add `Microsoft.Graph` package, to use [Microsoft Graph SDK](https://github.com/microsoftgraph/msgraph-sdk-dotnet/blob/dev/docs/overview.md).
154154
155-
```CSharp
156-
public interface IGraphApiOperations
157-
{
158-
Task<dynamic> GetUserInformation(string accessToken);
159-
Task<string> GetPhotoAsBase64Async(string accessToken);
160-
}
161-
```
155+
Add the `Services\*.cs` files. The `GraphServiceClientFactory.cs` returns a `GraphServiceClient` with an authentication provider, used for [Microsoft Graph SDK](https://github.com/microsoftgraph/msgraph-sdk-dotnet/blob/dev/docs/overview.md). Given an access token for Microsoft Graph, it's capable of making a request to Graph services sending that access token in the header.
162156
163157
### Update the `Startup.cs` file to enable the Microsoft Graph custom service
164158

@@ -175,36 +169,55 @@ In the `Controllers\HomeController.cs`file:
175169

176170
1. Add a constructor to HomeController, making the ITokenAcquisition service available (used by the ASP.NET dependency injection mechanism)
177171

178-
```CSharp
179-
public HomeController(ITokenAcquisition tokenAcquisition, IGraphApiOperations graphApiOperations)
180-
{
181-
this.tokenAcquisition = tokenAcquisition;
182-
this.graphApiOperations = graphApiOperations;
172+
```CSharp
173+
readonly ITokenAcquisition tokenAcquisition;
174+
readonly WebOptions webOptions;
183175

184-
}
185-
private ITokenAcquisition tokenAcquisition;
186-
private readonly IGraphApiOperations graphApiOperations;
187-
```
176+
public HomeController(ITokenAcquisition tokenAcquisition, IOptions<WebOptions> webOptionValue)
177+
{
178+
this.tokenAcquisition = tokenAcquisition;
179+
this.webOptions = webOptionValue.Value;
180+
}
181+
```
188182

189183
1. Add a `Profile()` action so that it calls the Microsoft Graph *me* endpoint. In case a token cannot be acquired, a challenge is attempted to re-sign-in the user, and have them consent to the requested scopes. This is expressed declaratively by the `AuthorizeForScopes`attribute. This attribute is part of the `Microsoft.Identity.Web` project and automatically manages incremental consent.
190184

191-
```CSharp
192-
[AuthorizeForScopes(Scopes = new[] {Constants.ScopeUserRead})]
193-
public async Task<IActionResult> Profile()
194-
{
195-
var accessToken =
196-
await tokenAcquisition.GetAccessTokenOnBehalfOfUser(HttpContext,
197-
new[] {Constants.ScopeUserRead});
198-
199-
var me = await graphApiOperations.GetUserInformation(accessToken);
200-
var photo = await graphApiOperations.GetPhotoAsBase64Async(accessToken);
185+
```CSharp
186+
[AuthorizeForScopes(Scopes = new[] { Constants.ScopeUserRead })]
187+
public async Task<IActionResult> Profile()
188+
{
189+
// Initialize the GraphServiceClient.
190+
Graph::GraphServiceClient graphClient = GetGraphServiceClient(new[] { Constants.ScopeUserRead });
201191

192+
var me = await graphClient.Me.Request().GetAsync();
202193
ViewData["Me"] = me;
203-
ViewData["Photo"] = photo;
194+
195+
try
196+
{
197+
// Get user photo
198+
using (var photoStream = await graphClient.Me.Photo.Content.Request().GetAsync())
199+
{
200+
byte[] photoByte = ((MemoryStream)photoStream).ToArray();
201+
ViewData["Photo"] = Convert.ToBase64String(photoByte);
202+
}
203+
}
204+
catch (System.Exception)
205+
{
206+
ViewData["Photo"] = null;
207+
}
204208

205209
return View();
206-
}
207-
```
210+
}
211+
212+
private Graph::GraphServiceClient GetGraphServiceClient(string[] scopes)
213+
{
214+
return GraphServiceClientFactory.GetAuthenticatedGraphClient(async () =>
215+
{
216+
string result = await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(scopes);
217+
return result;
218+
}, webOptions.GraphApiUrl);
219+
}
220+
```
208221

209222
### Add a Profile view to display the *me* object
210223

@@ -220,37 +233,50 @@ HTML table displaying the properties of the *me* object as returned by Microsoft
220233
<h3>@ViewData["Message"]</h3>
221234

222235
<table class="table table-striped table-condensed" style="font-family: monospace">
223-
<tr>
224-
<th>Property</th>
225-
<th>Value</th>
226-
</tr>
227-
<tr>
228-
<td>photo</td>
229-
<td>
230-
@{
231-
if (ViewData["photo"] != null)
232-
{
233-
<img style="margin: 5px 0; width: 150px" src="data:image/jpeg;base64, @ViewData["photo"]" />
234-
}
235-
else
236-
{
237-
<h3>NO PHOTO</h3>
238-
<p>Check user profile in Azure Active Directory to add a photo.</p>
239-
}
240-
}
241-
</td>
242-
</tr>
243-
@{
244-
var me = ViewData["me"] as JObject;
245-
var children = me.Properties();
246-
foreach (var child in children)
247-
{
248-
<tr>
249-
<td>@child.Name</td>
250-
<td>@child.Value</td>
251-
</tr>
236+
<tr>
237+
<th>Property</th>
238+
<th>Value</th>
239+
</tr>
240+
<tr>
241+
<td>photo</td>
242+
<td>
243+
@{
244+
if (ViewData["photo"] != null)
245+
{
246+
<img style="margin: 5px 0; width: 150px" src="data:image/jpeg;base64, @ViewData["photo"]" />
247+
}
248+
else
249+
{
250+
<h3>NO PHOTO</h3>
251+
<p>Check user profile in Azure Active Directory to add a photo.</p>
252+
}
253+
}
254+
</td>
255+
</tr>
256+
@{
257+
var me = ViewData["me"] as Microsoft.Graph.User;
258+
var properties = me.GetType().GetProperties();
259+
foreach (var child in properties)
260+
{
261+
object value = child.GetValue(me);
262+
string stringRepresentation;
263+
if (!(value is string) && value is IEnumerable<string>)
264+
{
265+
stringRepresentation = "["
266+
+ string.Join(", ", (value as IEnumerable<string>).OfType<object>().Select(c => c.ToString()))
267+
+ "]";
268+
}
269+
else
270+
{
271+
stringRepresentation = value?.ToString();
272+
}
273+
274+
<tr>
275+
<td> @child.Name </td>
276+
<td> @stringRepresentation </td>
277+
</tr>
278+
}
252279
}
253-
}
254280
</table>
255281
```
256282

0 commit comments

Comments
 (0)