├── SnippetsApp ├── Views │ ├── _ViewStart.cshtml │ ├── _ViewImports.cshtml │ ├── Shared │ │ ├── _ValidationScriptsPartial.cshtml │ │ ├── _AttachmentListPartial.cshtml │ │ ├── _AlertPartial.cshtml │ │ ├── Error.cshtml │ │ ├── _LoginPartial.cshtml │ │ └── _Layout.cshtml │ ├── Teams │ │ ├── _TeamListPartial.cshtml │ │ ├── _TeamGroupListPartial.cshtml │ │ ├── PostMessageToChannel.cshtml │ │ ├── Create.cshtml │ │ ├── _NonTeamGroupListPartial.cshtml │ │ ├── _ChannelListPartial.cshtml │ │ ├── _AppListPartial.cshtml │ │ ├── List.cshtml │ │ └── Display.cshtml │ ├── Users │ │ ├── _UserListPartial.cshtml │ │ ├── List.cshtml │ │ ├── AdminList.cshtml │ │ ├── Create.cshtml │ │ └── Display.cshtml │ ├── Mail │ │ ├── _RecipientListPartial.cshtml │ │ ├── Index.cshtml │ │ ├── _MessageListPartial.cshtml │ │ ├── New.cshtml │ │ └── Display.cshtml │ ├── Files │ │ ├── _FolderListPartial.cshtml │ │ ├── _SharedItemListPartial.cshtml │ │ ├── SharedWithMe.cshtml │ │ ├── NewFolder.cshtml │ │ ├── UploadFile.cshtml │ │ ├── Index.cshtml │ │ ├── _FileListPartial.cshtml │ │ ├── NewFile.cshtml │ │ ├── Drive.cshtml │ │ └── Display.cshtml │ ├── Home │ │ └── Index.cshtml │ ├── Groups │ │ ├── _GroupListPartial.cshtml │ │ ├── Create.cshtml │ │ ├── List.cshtml │ │ └── Display.cshtml │ ├── Calendar │ │ ├── _OrganizerTimePartial.cshtml │ │ ├── Index.cshtml │ │ ├── _AttendeeListPartial.cshtml │ │ ├── _DailyEventsPartial.cshtml │ │ ├── New.cshtml │ │ ├── Display.cshtml │ │ └── _AttendeeTimePartial.cshtml │ └── Extensions │ │ └── Index.cshtml ├── wwwroot │ ├── favicon.ico │ ├── img │ │ ├── no-profile-photo.png │ │ └── no-profile-photo-lg.png │ ├── js │ │ └── site.js │ ├── lib │ │ ├── jquery-validation-unobtrusive │ │ │ ├── LICENSE.txt │ │ │ └── jquery.validate.unobtrusive.min.js │ │ ├── jquery-validation │ │ │ └── LICENSE.md │ │ ├── bootstrap │ │ │ ├── LICENSE │ │ │ └── dist │ │ │ │ └── css │ │ │ │ ├── bootstrap-reboot.min.css │ │ │ │ └── bootstrap-reboot.css │ │ └── jquery │ │ │ └── LICENSE.txt │ └── css │ │ └── site.css ├── appsettings.Development.json ├── Models │ ├── ErrorViewModel.cs │ ├── UsersListDisplayModel.cs │ ├── TeamMessageDisplayModel.cs │ ├── TeamDisplayModel.cs │ ├── DailyViewModel.cs │ ├── MailViewDisplayModel.cs │ ├── GroupsListDisplayModel.cs │ ├── Alert.cs │ ├── FilesViewDisplayModel.cs │ ├── NewEvent.cs │ ├── TeamsListDisplayModel.cs │ ├── CalendarViewEvent.cs │ ├── GroupWithPhoto.cs │ ├── UserWithPhoto.cs │ ├── RoamingSettings.cs │ ├── RoamingSettingsDisplayModel.cs │ └── CalendarViewModel.cs ├── appsettings.json ├── Properties │ └── launchSettings.json ├── SnippetsApp.csproj ├── Program.cs ├── Controllers │ ├── HomeController.cs │ ├── BaseController.cs │ └── ExtensionsController.cs ├── TagHelpers │ └── DateTimeOffsetTagHelper.cs ├── Alerts │ ├── WithAlertResult.cs │ └── AlertExtensions.cs ├── libman.json ├── Graph │ ├── GraphConstants.cs │ └── GraphClaimsPrincipalExtensions.cs └── Startup.cs ├── .gitattributes ├── CODE_OF_CONDUCT.md ├── aspnet-snippets-sample.yml ├── .github └── ISSUE_TEMPLATE │ ├── ask-a-question.md │ └── bug_report.md ├── LICENSE ├── .vscode ├── launch.json └── tasks.json ├── SECURITY.md ├── .gitignore ├── README-Localized ├── README-zh-tw.md ├── README-zh-cn.md └── README-ja-jp.md └── README.md /SnippetsApp/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /SnippetsApp/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/aspnet-snippets-sample/main/SnippetsApp/wwwroot/favicon.ico -------------------------------------------------------------------------------- /SnippetsApp/wwwroot/img/no-profile-photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/aspnet-snippets-sample/main/SnippetsApp/wwwroot/img/no-profile-photo.png -------------------------------------------------------------------------------- /SnippetsApp/wwwroot/img/no-profile-photo-lg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/aspnet-snippets-sample/main/SnippetsApp/wwwroot/img/no-profile-photo-lg.png -------------------------------------------------------------------------------- /SnippetsApp/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using SnippetsApp 2 | @using SnippetsApp.Models 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | @addTagHelper *, SnippetsApp 5 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /SnippetsApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SnippetsApp/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /SnippetsApp/Models/ErrorViewModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | namespace SnippetsApp.Models 5 | { 6 | public class ErrorViewModel 7 | { 8 | public string RequestId { get; set; } 9 | 10 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /SnippetsApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "AzureAd": { 3 | "Instance": "https://login.microsoftonline.com/", 4 | "TenantId": "common", 5 | "CallbackPath": "/signin-oidc" 6 | }, 7 | "Logging": { 8 | "LogLevel": { 9 | "Default": "Information", 10 | "Microsoft": "Warning", 11 | "Microsoft.Hosting.Lifetime": "Information" 12 | } 13 | }, 14 | "AllowedHosts": "*" 15 | } 16 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Teams/_TeamListPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @using Microsoft.Graph 5 | 6 | @model IEnumerable 7 | 8 |
9 | @foreach (var team in Model) 10 | { 11 | @team.DisplayName 12 | } 13 |
14 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Teams/_TeamGroupListPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @using Microsoft.Graph 5 | 6 | @model IEnumerable 7 | 8 |
9 | @foreach (var group in Model) 10 | { 11 | @group.DisplayName 12 | } 13 |
14 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Users/_UserListPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model IEnumerable 5 | 6 | @{ 7 | ViewData["Title"] = "List users"; 8 | } 9 | 10 |
11 | @foreach (var user in Model) 12 | { 13 | @user.DisplayName 14 | } 15 |
16 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Users/List.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model UsersListDisplayModel 5 | 6 | @{ 7 | ViewData["Title"] = "List users"; 8 | } 9 | 10 | @if (!string.IsNullOrEmpty(Model.NextPageUrl)) 11 | { 12 | Next page 13 | } 14 | 15 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Mail/_RecipientListPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model IEnumerable 5 | 6 | @using Microsoft.Graph 7 | 8 | @{ 9 | var recipientString = ""; 10 | foreach (var recipient in Model) 11 | { 12 | if (!string.IsNullOrEmpty(recipientString)) 13 | { 14 | recipientString += "; "; 15 | } 16 | recipientString += recipient.EmailAddress.Name; 17 | } 18 | } 19 | 20 | @recipientString 21 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Files/_FolderListPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model IEnumerable 5 | 6 | @using Microsoft.Graph 7 | 8 | @foreach(var folder in Model) 9 | { 10 | 11 |
12 | 13 |
@folder.Name
14 |
15 |
16 | } -------------------------------------------------------------------------------- /SnippetsApp/Models/UsersListDisplayModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using Microsoft.Graph; 6 | 7 | namespace SnippetsApp.Models 8 | { 9 | // The view model for the user list pages 10 | public class UsersListDisplayModel 11 | { 12 | // List of users 13 | public List UsersList { get; set; } 14 | 15 | // URL to next page of results 16 | public string NextPageUrl { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | - Employees can reach out at [aka.ms/opensource/moderation-support](https://aka.ms/opensource/moderation-support) 11 | -------------------------------------------------------------------------------- /SnippetsApp/Models/TeamMessageDisplayModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | namespace SnippetsApp.Models 5 | { 6 | // The view model for post a message to channel page 7 | public class TeamMessageDisplayModel 8 | { 9 | // The channel ID for this message 10 | public string ChannelId { get; set; } 11 | 12 | // The team ID for this message 13 | public string TeamId { get; set; } 14 | 15 | // The message content 16 | public string Message { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Shared/_AttachmentListPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model IEnumerable 5 | 6 | @using Microsoft.Graph 7 | 8 | @{ 9 | var attachmentString = ""; 10 | foreach (var attachment in Model) 11 | { 12 | if (attachment.IsInline.Equals(true)) 13 | { 14 | continue; 15 | } 16 | 17 | if (!string.IsNullOrEmpty(attachmentString)) 18 | { 19 | attachmentString += "; "; 20 | } 21 | 22 | attachmentString += attachment.Name; 23 | } 24 | } 25 | 26 | @attachmentString 27 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Files/_SharedItemListPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model IEnumerable 5 | 6 | @using Microsoft.Graph 7 | 8 | @foreach(var item in Model) 9 | { 10 |
11 | 12 |
@item.RemoteItem.Name
13 |
Shared by: @item.RemoteItem.Shared.SharedBy.User.DisplayName
14 |
15 | } -------------------------------------------------------------------------------- /SnippetsApp/Models/TeamDisplayModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using Microsoft.Graph; 6 | 7 | namespace SnippetsApp.Models 8 | { 9 | // The view model for the team display page 10 | public class TeamDisplayModel 11 | { 12 | // The team 13 | public Team Team { get; set; } 14 | 15 | // List of channels 16 | public IList Channels { get; set; } 17 | 18 | // List of installed apps 19 | public IList InstalledApps { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SnippetsApp/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Teams/PostMessageToChannel.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model TeamMessageDisplayModel 5 | 6 | @{ 7 | ViewData["Title"] = "New message"; 8 | } 9 | 10 |

Post message to channel

11 |
12 | 13 | 14 | 15 | 16 | Cancel 17 |
18 | -------------------------------------------------------------------------------- /SnippetsApp/Models/DailyViewModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | // 5 | using System; 6 | using System.Collections.Generic; 7 | 8 | namespace SnippetsApp.Models 9 | { 10 | public class DailyViewModel 11 | { 12 | // Day the view is for 13 | public DateTime Day { get; private set; } 14 | // Events on this day 15 | public IEnumerable Events { get; private set; } 16 | 17 | public DailyViewModel(DateTime day, IEnumerable events) 18 | { 19 | Day = day; 20 | Events = events; 21 | } 22 | } 23 | } 24 | // 25 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Files/SharedWithMe.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model FilesViewDisplayModel 5 | 6 | @{ 7 | ViewData["Title"] = $"Shared with me"; 8 | } 9 | 10 | @if (!string.IsNullOrEmpty(Model.NextPageUrl)) 11 | { 12 | Next page 13 | } 14 | 15 |

Shared with me

16 | 17 |
18 | @if(Model.Folders.Count > 0) 19 | { 20 | 21 | } 22 | @if(Model.Files.Count > 0) 23 | { 24 | 25 | } 26 |
-------------------------------------------------------------------------------- /SnippetsApp/Models/MailViewDisplayModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using Microsoft.Graph; 6 | 7 | namespace SnippetsApp.Models 8 | { 9 | // The view model for the mail page 10 | public class MailViewDisplayModel 11 | { 12 | // List of all mail folders 13 | public IList MailFolders { get; set; } 14 | 15 | // Currently selected folder 16 | public MailFolder SelectedFolder { get; set; } 17 | 18 | // Current page of messages 19 | public IList Messages { get; set; } 20 | 21 | // URL to next page of results 22 | public string NextPageUrl { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /aspnet-snippets-sample.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:Sample 2 | sample: 3 | - name: Microsoft Graph Snippets Sample for ASP.NET 4.6 4 | path: '' 5 | description: A repository of code snippets that use Microsoft Graph to perform common tasks such as sending email, managing groups, and other activities from an ASP.NET MVC app. This sample uses the Microsoft Graph .NET Client Library to work with data, and the Microsoft Authentication Library (MSAL) for authentication on the Azure AD v2.0 endpoint. 6 | readme: '' 7 | generateZip: FALSE 8 | isLive: TRUE 9 | technologies: 10 | - Microsoft Graph 11 | azureDeploy: '' 12 | author: jamescro 13 | platforms: [] 14 | languages: 15 | - C# 16 | extensions: 17 | products: 18 | - Office 365 19 | scenarios: [] 20 | -------------------------------------------------------------------------------- /SnippetsApp/Models/GroupsListDisplayModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using Microsoft.Graph; 6 | 7 | namespace SnippetsApp.Models 8 | { 9 | // The view model for the user list pages 10 | public class GroupsListDisplayModel 11 | { 12 | // List of all groups 13 | public IList AllGroups { get; set; } 14 | 15 | // List of all unified groups 16 | public IList UnifiedGroups { get; set; } 17 | 18 | // List of groups user is a member of 19 | public IList GroupMemberships { get; set; } 20 | 21 | // List of groups user owns 22 | public IList OwnedGroups { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SnippetsApp/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:64461", 7 | "sslPort": 44388 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "SnippetsApp": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 22 | "environmentVariables": { 23 | "ASPNETCORE_ENVIRONMENT": "Development" 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /SnippetsApp/Models/Alert.cs: -------------------------------------------------------------------------------- 1 | namespace SnippetsApp.Models 2 | { 3 | // Represents a Bootstrap alert 4 | public class Alert 5 | { 6 | // "success", "error", "info", etc. 7 | public string Type { get; set; } 8 | 9 | // The main text to display in the alert 10 | public string Message { get; set; } 11 | 12 | // Optional debug information, rendered as 13 | // preformatted code 14 | public string DebugInfo { get; set; } 15 | 16 | // If the alert contains a button, this 17 | // is the text on the button 18 | public string ActionText { get; set; } 19 | 20 | // If the alert contains a button, this is 21 | // the href for the button 22 | public string ActionUrl { get; set; } 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Files/NewFolder.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model string 5 | 6 | @{ 7 | ViewData["Title"] = "New folder"; 8 | } 9 | 10 |
11 |
12 |

New folder

13 |
14 | 15 | 16 |
17 | 18 | Cancel 19 |
20 |
21 |
22 |
23 | -------------------------------------------------------------------------------- /SnippetsApp/Models/FilesViewDisplayModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using Microsoft.Graph; 6 | 7 | namespace SnippetsApp.Models 8 | { 9 | // The view model for the Files page 10 | public class FilesViewDisplayModel 11 | { 12 | // List of all child folders in current view 13 | public IList Folders { get; set; } 14 | 15 | // List of all child files in current view 16 | public IList Files { get; set; } 17 | 18 | // Currently selected folder 19 | public DriveItem SelectedFolder { get; set; } 20 | 21 | // URL to next page of results 22 | public string NextPageUrl { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Teams/Create.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @{ 5 | ViewData["Title"] = "Create new group and team"; 6 | } 7 | 8 |

Create new group and team

9 |
10 |
11 | 12 | 13 |
14 |
15 | 16 | 17 |
18 | 19 | Cancel 20 |
21 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @{ 5 | ViewData["Title"] = "Home Page"; 6 | } 7 | 8 | @using SnippetsApp 9 | 10 |
11 |

Microsoft Graph ASP.NET Core Snippets App

12 |

This sample app shows how to use the Microsoft Graph API to access a user's data from ASP.NET Core

13 | @if (User.Identity.IsAuthenticated) 14 | { 15 |

Welcome @User.GetUserGraphDisplayName()!

16 |

Use the navigation bar at the top of the page to get started.

17 | } 18 | else 19 | { 20 | Click here to sign in 21 | } 22 |
23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/ask-a-question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Ask a question 3 | about: Ask a question about Graph, adding features to this sample, etc. 4 | title: '' 5 | labels: question, needs triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | Thank you for taking an interest in Microsoft Graph development! Please feel free to ask a question here, but keep in mind the following: 11 | 12 | - This is not an official Microsoft support channel, and our ability to respond to questions here is limited. Questions about Graph, or questions about adding a new feature to the sample, will be answered on a best-effort basis. 13 | - Questions should be asked on [Stack Overflow](https://stackoverflow.com/questions/tagged/microsoft-graph). 14 | - Issues with Microsoft Graph itself should be handled through [support](https://developer.microsoft.com/graph/support). 15 | -------------------------------------------------------------------------------- /SnippetsApp/Models/NewEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | // 5 | using System; 6 | using System.ComponentModel.DataAnnotations; 7 | 8 | namespace SnippetsApp.Models 9 | { 10 | public class NewEvent 11 | { 12 | [Required] 13 | public string Subject { get; set; } 14 | public DateTime Start { get; set; } 15 | public DateTime End { get; set; } 16 | [DataType(DataType.MultilineText)] 17 | public string Body { get; set; } 18 | [RegularExpression(@"((\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*)*([;])*)*", 19 | ErrorMessage="Please enter one or more email addresses separated by a semi-colon (;)")] 20 | public string Attendees { get; set; } 21 | } 22 | } 23 | // 24 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Teams/_NonTeamGroupListPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @using Microsoft.Graph 5 | 6 | @model IEnumerable 7 | 8 |
9 | @foreach (var group in Model) 10 | { 11 |
12 |
13 |
14 | @group.DisplayName 15 |
16 |
17 | 18 | 19 |
20 |
21 |
22 | } 23 |
24 | -------------------------------------------------------------------------------- /SnippetsApp/SnippetsApp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 702a3216-2ff2-4901-be95-13c2feec7d6e 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /SnippetsApp/Models/TeamsListDisplayModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using Microsoft.Graph; 6 | 7 | namespace SnippetsApp.Models 8 | { 9 | // The view model for the teams list pages 10 | public class TeamsListDisplayModel 11 | { 12 | // List of all teams 13 | public IList AllTeams { get; set; } 14 | 15 | // List of all groups that do not have teams 16 | public IList AllNonTeamGroups { get; set; } 17 | 18 | // List of teams user is a member of 19 | public IList JoinedTeams { get; set; } 20 | 21 | public TeamsListDisplayModel() 22 | { 23 | AllTeams = new List(); 24 | AllNonTeamGroups = new List(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Teams/_ChannelListPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model IEnumerable 5 | 6 | @using Microsoft.Graph 7 | 8 | @{ 9 | var teamArchived = ViewData["teamArchived"] as bool?; 10 | } 11 | 12 |
13 | @foreach (var channel in Model) 14 | { 15 |
16 |
17 |
18 | @channel.DisplayName 19 |
20 | @if (!teamArchived.Value) 21 | { 22 | Post message 26 | } 27 |
28 |
29 | } 30 |
31 | -------------------------------------------------------------------------------- /SnippetsApp/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | using Microsoft.AspNetCore.Hosting; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.Hosting; 11 | using Microsoft.Extensions.Logging; 12 | 13 | namespace SnippetsApp 14 | { 15 | public class Program 16 | { 17 | public static void Main(string[] args) 18 | { 19 | CreateHostBuilder(args).Build().Run(); 20 | } 21 | 22 | public static IHostBuilder CreateHostBuilder(string[] args) => 23 | Host.CreateDefaultBuilder(args) 24 | .ConfigureWebHostDefaults(webBuilder => 25 | { 26 | webBuilder.UseStartup(); 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Teams/_AppListPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model IEnumerable 5 | 6 | @using Microsoft.Graph 7 | 8 |
9 | @foreach (var app in Model) 10 | { 11 |
12 |
13 |
14 | @app.TeamsAppDefinition.DisplayName 15 | @app.TeamsAppDefinition.Version 16 |
17 |
18 | 19 | 20 | 21 |
22 |
23 |
24 | } 25 |
26 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Groups/_GroupListPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @using Microsoft.Graph 5 | 6 | @model IEnumerable 7 | 8 |
9 | @foreach (var group in Model) 10 | { 11 |
12 |
13 |
14 | @group.DisplayName 15 |
16 | Display 17 |
18 | 19 | 20 |
21 |
22 |
23 | } 24 |
25 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Shared/_AlertPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @{ 5 | var type = $"{TempData["_alertType"]}"; 6 | var message = $"{TempData["_alertMessage"]}"; 7 | var debugInfo = $"{TempData["_alertDebugInfo"]}"; 8 | var actionUrl = $"{TempData["_alertActionUrl"]}"; 9 | var actionText = $"{TempData["_alertActionText"]}"; 10 | 11 | var alerts = TempData.GetAlerts("_alertData"); 12 | } 13 | 14 | @foreach (var alert in alerts) 15 | { 16 | 27 | } 28 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model ErrorViewModel 2 | @{ 3 | ViewData["Title"] = "Error"; 4 | } 5 | 6 |

Error.

7 |

An error occurred while processing your request.

8 | 9 | @if (Model.ShowRequestId) 10 | { 11 |

12 | Request ID: @Model.RequestId 13 |

14 | } 15 | 16 |

Development Mode

17 |

18 | Swapping to Development environment will display more detailed information about the error that occurred. 19 |

20 |

21 | The Development environment shouldn't be enabled for deployed applications. 22 | It can result in displaying sensitive information from exceptions to end users. 23 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 24 | and restarting the app. 25 |

26 | -------------------------------------------------------------------------------- /SnippetsApp/Models/CalendarViewEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | // 5 | using System; 6 | using Microsoft.Graph; 7 | 8 | namespace SnippetsApp.Models 9 | { 10 | public class CalendarViewEvent 11 | { 12 | public string Id { get; private set; } 13 | public string Subject { get; private set; } 14 | public string Organizer { get; private set; } 15 | public DateTime Start { get; private set; } 16 | public DateTime End { get; private set; } 17 | 18 | public CalendarViewEvent(Event graphEvent) 19 | { 20 | Id = graphEvent.Id; 21 | Subject = graphEvent.Subject; 22 | Organizer = graphEvent.Organizer.EmailAddress.Name; 23 | Start = DateTime.Parse(graphEvent.Start.DateTime); 24 | End = DateTime.Parse(graphEvent.End.DateTime); 25 | } 26 | } 27 | } 28 | // 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug, needs triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 16 | 1. Go to '...' 17 | 2. Click on '....' 18 | 3. Scroll down to '....' 19 | 4. See error 20 | 21 | **Expected behavior** 22 | A clear and concise description of what you expected to happen. 23 | 24 | **Screenshots** 25 | If applicable, add screenshots to help explain your problem. 26 | 27 | **Desktop (please complete the following information):** 28 | 29 | - OS: [e.g. iOS] 30 | - Browser [e.g. chrome, safari] 31 | - Version [e.g. 22] 32 | 33 | **Dependency versions** 34 | 35 | - Authentication library (MSAL, etc.) version: 36 | - Graph library (Graph SDK, REST library, etc.) version: 37 | 38 | **Additional context** 39 | Add any other context about the problem here. 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Microsoft Corporation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": ".NET Core Launch (web)", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | // If you have changed target frameworks, make sure to update the program path. 13 | "program": "${workspaceFolder}/SnippetsApp/bin/Debug/net5.0/SnippetsApp.dll", 14 | "args": [], 15 | "cwd": "${workspaceFolder}/SnippetsApp", 16 | "stopAtEntry": false, 17 | // Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser 18 | "serverReadyAction": { 19 | "action": "openExternally", 20 | "pattern": "^\\s*Now listening on:\\s+(https?://\\S+)" 21 | }, 22 | "env": { 23 | "ASPNETCORE_ENVIRONMENT": "Development" 24 | }, 25 | "sourceFileMap": { 26 | "/Views": "${workspaceFolder}/SnippetsApp/Views" 27 | } 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /SnippetsApp/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Calendar/_OrganizerTimePartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model Event 5 | 6 | @using Microsoft.Graph 7 | 8 | @{ 9 | var start = DateTimeOffset.Parse(Model.Start.DateTime); 10 | var end = DateTimeOffset.Parse(Model.End.DateTime); 11 | } 12 | 13 |
14 | 15 |
16 |
17 | 18 | 19 | 20 |
21 |
22 | 23 | 24 | 25 |
26 |
27 | 28 |
29 | -------------------------------------------------------------------------------- /SnippetsApp/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2020 Twitter, Inc. 4 | Copyright (c) 2011-2020 The Bootstrap Authors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Mail/Index.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model MailViewDisplayModel 5 | 6 | @{ 7 | string folderName = Model.SelectedFolder == null ? "All folders" : 8 | Model.SelectedFolder.DisplayName; 9 | ViewData["Title"] = $"Mail - {folderName}"; 10 | } 11 | 12 |
13 | 14 | 22 |
23 | New message 24 | 25 | @if (!string.IsNullOrEmpty(Model.NextPageUrl)) 26 | { 27 | Next page 28 | } 29 | 30 |

@folderName

31 | 32 | 33 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Calendar/Index.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | @model CalendarViewModel 6 | 7 | @{ 8 | ViewData["Title"] = "Calendar"; 9 | } 10 | 11 |
12 |

@Model.TimeSpan()

13 | New event 14 |
15 |
16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
DateTimeEvent
35 |
36 |
37 | 38 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Shared/_LoginPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | @using SnippetsApp 6 | 7 | 30 | 31 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Calendar/_AttendeeListPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model IEnumerable 5 | 6 | @using Microsoft.Graph 7 | 8 | @{ 9 | var requiredAttendees = ""; 10 | var optionalAttendees = ""; 11 | 12 | foreach (var attendee in Model) 13 | { 14 | if (attendee.Type.Equals(AttendeeType.Required)) 15 | { 16 | if (!string.IsNullOrEmpty(requiredAttendees)) 17 | { 18 | requiredAttendees += "; "; 19 | } 20 | 21 | requiredAttendees += attendee.EmailAddress.Name; 22 | } 23 | else if (attendee.Type.Equals(AttendeeType.Optional)) 24 | { 25 | if (!string.IsNullOrEmpty(optionalAttendees)) 26 | { 27 | optionalAttendees += "; "; 28 | } 29 | 30 | optionalAttendees += attendee.EmailAddress.Name; 31 | } 32 | } 33 | } 34 | 35 | @if (!string.IsNullOrEmpty(requiredAttendees)) 36 | { 37 |
38 |
Required:
39 |
@requiredAttendees
40 |
41 | } 42 | @if (!string.IsNullOrEmpty(optionalAttendees)) 43 | { 44 |
45 |
Optional:
46 |
@optionalAttendees
47 |
48 | } 49 | -------------------------------------------------------------------------------- /SnippetsApp/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | using SnippetsApp.Models; 4 | using Microsoft.AspNetCore.Authorization; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Logging; 7 | using System.Diagnostics; 8 | 9 | namespace SnippetsApp.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | private readonly ILogger _logger; 14 | 15 | public HomeController( 16 | ILogger logger) 17 | { 18 | _logger = logger; 19 | } 20 | 21 | public IActionResult Index() 22 | { 23 | return View(); 24 | } 25 | 26 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 27 | public IActionResult Error() 28 | { 29 | return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); 30 | } 31 | 32 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 33 | [AllowAnonymous] 34 | public IActionResult ErrorWithMessage(string message, string debug) 35 | { 36 | return View("Index").WithError(message, debug); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Files/UploadFile.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model string 5 | 6 | @{ 7 | ViewData["Title"] = "Upload file"; 8 | } 9 | 10 |
11 |
12 |

Upload file

13 |
14 | 15 |
16 |
17 | 18 | 19 |
20 |
21 |
22 | 23 | Cancel 24 |
25 |
26 |
27 |
28 | 29 | @section Scripts 30 | { 31 | 32 | 38 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "build", 10 | "${workspaceFolder}/SnippetsApp/SnippetsApp.csproj", 11 | "/property:GenerateFullPaths=true", 12 | "/consoleloggerparameters:NoSummary" 13 | ], 14 | "problemMatcher": "$msCompile" 15 | }, 16 | { 17 | "label": "publish", 18 | "command": "dotnet", 19 | "type": "process", 20 | "args": [ 21 | "publish", 22 | "${workspaceFolder}/SnippetsApp/SnippetsApp.csproj", 23 | "/property:GenerateFullPaths=true", 24 | "/consoleloggerparameters:NoSummary" 25 | ], 26 | "problemMatcher": "$msCompile" 27 | }, 28 | { 29 | "label": "watch", 30 | "command": "dotnet", 31 | "type": "process", 32 | "args": [ 33 | "watch", 34 | "run", 35 | "${workspaceFolder}/SnippetsApp/SnippetsApp.csproj", 36 | "/property:GenerateFullPaths=true", 37 | "/consoleloggerparameters:NoSummary" 38 | ], 39 | "problemMatcher": "$msCompile" 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Users/AdminList.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model UsersListDisplayModel 5 | 6 | @{ 7 | ViewData["Title"] = "Manage users"; 8 | } 9 | 10 |
11 |
12 | @if (!string.IsNullOrEmpty(Model.NextPageUrl)) 13 | { 14 | Next page 15 | } 16 |
17 |
18 | Create user 19 |
20 |
21 |
22 | @foreach (var user in Model.UsersList) 23 | { 24 |
25 |
26 |
@user.DisplayName
27 | Display 28 |
29 | 30 | 31 |
32 |
33 |
34 | } 35 |
36 | -------------------------------------------------------------------------------- /SnippetsApp/Models/GroupWithPhoto.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using System.IO; 6 | using Microsoft.Graph; 7 | 8 | namespace SnippetsApp.Models 9 | { 10 | // Graph Group object plus photo 11 | public class GroupWithPhoto 12 | { 13 | public Group Group { get; set; } 14 | public string ProfilePhotoUri { get; set; } 15 | 16 | public GroupWithPhoto() 17 | { 18 | Group = null; 19 | // Use default image if the group doesn't have a profile 20 | // photo 21 | ProfilePhotoUri = "/img/no-profile-photo-lg.png"; 22 | } 23 | 24 | public void AddGroupPhoto(Stream photoStream) 25 | { 26 | if (photoStream != null) 27 | { 28 | // Copy the photo stream to a memory stream 29 | // to get the bytes out of it 30 | var memoryStream = new MemoryStream(); 31 | photoStream.CopyTo(memoryStream); 32 | var photoBytes = memoryStream.ToArray(); 33 | 34 | // Generate a date URI for the photo 35 | var photoUri = $"data:image/png;base64,{Convert.ToBase64String(photoBytes)}"; 36 | ProfilePhotoUri = photoUri; 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /SnippetsApp/Views/Users/Create.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model string 5 | 6 | @{ 7 | ViewData["Title"] = "Create user"; 8 | string domainName = $"@{Model}"; 9 | } 10 | 11 |
12 |
13 | 14 | 15 |
16 |
17 | 18 | 19 |
20 | 21 |
22 | @domainName 23 |
24 |
25 |
26 |
27 | 28 | 29 |
30 |
31 | 32 | 33 |
34 | 35 | Cancel 36 |
37 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Groups/Create.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @{ 5 | ViewData["Title"] = "Create group"; 6 | } 7 | 8 |
9 |
10 | 11 | 12 |
13 |
14 | 15 | 16 |
17 |
18 | 19 | 20 |
21 |
22 | 23 | 24 |
25 |
26 | 27 | 28 |
29 | 30 | Cancel 31 |
32 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Files/Index.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model FilesViewDisplayModel 5 | 6 | @{ 7 | string folderName = Model.SelectedFolder == null ? "Root" : 8 | Model.SelectedFolder.Name; 9 | ViewData["Title"] = $"Files - {folderName}"; 10 | } 11 | 12 | @if (!string.IsNullOrEmpty(Model.SelectedFolder.ParentReference.Id)) 13 | { 14 | Back 15 | } 16 | 17 | Create file 18 | Upload file 19 | Create folder 20 | 21 | @if (!string.IsNullOrEmpty(Model.NextPageUrl)) 22 | { 23 | Next page 24 | } 25 | 26 |

@folderName

27 | 28 |
29 | @if(Model.Folders.Count > 0) 30 | { 31 | 32 | } 33 | @if(Model.Files.Count > 0) 34 | { 35 | 36 | } 37 |
-------------------------------------------------------------------------------- /SnippetsApp/Views/Mail/_MessageListPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model IEnumerable 5 | 6 | @using Microsoft.Graph 7 | 8 | @{ 9 | string dateTimeFormat = $"{User.GetUserGraphDateFormat()} {User.GetUserGraphTimeFormat()}"; 10 | } 11 | 12 | 39 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Files/_FileListPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model IEnumerable 5 | 6 | @using Microsoft.Graph 7 | 8 | @{ 9 | string format = $"{User.GetUserGraphDateFormat()} {User.GetUserGraphTimeFormat()}"; 10 | } 11 | 12 | @foreach(var file in Model) 13 | { 14 | 15 |
16 |
17 |
18 | @if (file.Thumbnails.CurrentPage.Count > 0) 19 | { 20 | 21 | } 22 | else 23 | { 24 | 25 | } 26 |
27 |
28 |
29 |
@file.Name
30 |

31 | Modified: 32 | 33 | by @file.LastModifiedBy.User.DisplayName 34 |

35 |
36 |
37 |
38 |
39 |
40 | } -------------------------------------------------------------------------------- /SnippetsApp/Models/UserWithPhoto.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using Microsoft.Graph; 8 | 9 | namespace SnippetsApp.Models 10 | { 11 | // Graph User object plus extra info about the user: 12 | // Photo, manager, direct reports 13 | public class UserWithPhoto 14 | { 15 | public User User { get; set; } 16 | public string ProfilePhotoUri { get; set; } 17 | public List Manager { get; set; } 18 | public List DirectReports { get; set; } 19 | 20 | public UserWithPhoto() 21 | { 22 | User = null; 23 | // Use default image if the user doesn't have a profile 24 | // photo 25 | ProfilePhotoUri = "/img/no-profile-photo-lg.png"; 26 | } 27 | 28 | public void AddUserPhoto(Stream photoStream) 29 | { 30 | if (photoStream != null) 31 | { 32 | // Copy the photo stream to a memory stream 33 | // to get the bytes out of it 34 | var memoryStream = new MemoryStream(); 35 | photoStream.CopyTo(memoryStream); 36 | var photoBytes = memoryStream.ToArray(); 37 | 38 | // Generate a date URI for the photo 39 | var photoUri = $"data:image/png;base64,{Convert.ToBase64String(photoBytes)}"; 40 | ProfilePhotoUri = photoUri; 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /SnippetsApp/Views/Files/NewFile.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model string 5 | 6 | @{ 7 | ViewData["Title"] = "New file"; 8 | } 9 | 10 |
11 |
12 |

New file

13 | 16 |
17 | 18 |
19 |
20 | 21 | 22 |
23 |
24 |
25 | 26 | Cancel 27 |
28 |
29 |
30 |
31 | 32 | @section Scripts 33 | { 34 | 35 | 41 | } -------------------------------------------------------------------------------- /SnippetsApp/Views/Teams/List.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model TeamsListDisplayModel 5 | 6 | @{ 7 | ViewData["Title"] = "List teams"; 8 | } 9 | 10 |
11 |
12 | 23 |
24 |
25 | Create new team 26 |
27 |
28 | 29 |
30 |
31 | 32 |
33 |
34 | 35 |
36 |
37 | 38 |
39 |
40 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Files/Drive.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model Drive 5 | 6 | @using Microsoft.Graph 7 | @using ByteSizeLib 8 | 9 | @{ 10 | ViewData["Title"] = Model.Name; 11 | string stateClass = "text-critical"; 12 | if (Model.Quota.State == "normal") 13 | { 14 | stateClass = "text-success"; 15 | } 16 | else if (Model.Quota.State == "nearing") 17 | { 18 | stateClass = "text-warning"; 19 | } 20 | } 21 | 22 |
23 |
24 |

@Model.Name

25 | @if(!string.IsNullOrEmpty(Model.Description)) 26 | { 27 |

@Model.Description

28 | } 29 |
30 |
State:
31 |
@Model.Quota.State
32 |
33 |
34 |
Capacity:
35 |
@ByteSize.FromBytes(Model.Quota.Total.Value).ToString()
36 |
37 |
38 |
Used:
39 |
@ByteSize.FromBytes(Model.Quota.Used.Value).ToString()
40 |
41 |
42 |
Available:
43 |
@ByteSize.FromBytes(Model.Quota.Remaining.Value).ToString()
44 |
45 |
46 |
Recycle bin:
47 |
@ByteSize.FromBytes(Model.Quota.Deleted.Value).ToString()
48 |
49 |
50 |
51 | -------------------------------------------------------------------------------- /SnippetsApp/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Mail/New.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @{ 5 | ViewData["Title"] = "New message"; 6 | } 7 | 8 |

New message

9 |
10 |
11 | 12 |
13 | 14 |
15 |
16 |
17 | 18 |
19 | 20 |
21 |
22 |
23 | 24 |
25 |
26 | 27 | 28 |
29 |
30 |
31 | 32 |
33 | 34 | Cancel 35 |
36 |
37 | 38 | @section Scripts 39 | { 40 | 41 | 47 | } 48 | -------------------------------------------------------------------------------- /SnippetsApp/TagHelpers/DateTimeOffsetTagHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.Razor.TagHelpers; 6 | using TimeZoneConverter; 7 | 8 | namespace SnippetsApp.TagHelpers 9 | { 10 | // This tag helper formats a DateTimeOffset using 11 | // the specified time zone and format 12 | // Usage: 13 | // 14 | public class DateTimeOffsetTagHelper : TagHelper 15 | { 16 | public DateTimeOffset? Value { get; set; } 17 | public string TimeZone { get; set; } 18 | public string Format { get; set; } 19 | public override void Process(TagHelperContext context, TagHelperOutput output) 20 | { 21 | if (string.IsNullOrWhiteSpace(Format)) 22 | { 23 | // Handle empty format 24 | // Default to 25 | Format = "g"; 26 | } 27 | 28 | DateTime dateTime; 29 | try 30 | { 31 | // TZConvert handles either an IANA or Windows identifier 32 | // Graph can return either 33 | var userTimeZone = TZConvert.GetTimeZoneInfo(TimeZone); 34 | dateTime = TimeZoneInfo.ConvertTimeFromUtc(Value.GetValueOrDefault().UtcDateTime, userTimeZone); 35 | } 36 | catch(TimeZoneNotFoundException) 37 | { 38 | // If the time zone isn't found, just use 39 | dateTime = Value.GetValueOrDefault().UtcDateTime; 40 | } 41 | 42 | output.TagName = "span"; 43 | output.Content.SetContent(dateTime.ToString(Format)); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Extensions/Index.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model RoamingSettingsDisplayModel 5 | 6 | @{ 7 | ViewData["Title"] = "Roaming settings"; 8 | string formAction = Model.Settings == null ? "Create" : "Update"; 9 | } 10 | 11 |
12 |
13 |

Roaming settings

14 | @if (Model.Settings == null) 15 | { 16 |
17 | No settings found. Use the form below to add roaming settings to your profile. 18 |
19 | } 20 | else 21 | { 22 |
23 | 24 |
25 | } 26 |
27 |
28 | 29 | 32 |
33 |
34 | 35 | 38 |
39 |
40 | 41 | 44 |
45 | 46 |
47 |
48 |
49 | -------------------------------------------------------------------------------- /SnippetsApp/Alerts/WithAlertResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | // 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.AspNetCore.Mvc.ViewFeatures; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using SnippetsApp.Models; 10 | 11 | namespace SnippetsApp 12 | { 13 | // WithAlertResult adds temporary error/info/success 14 | // messages to the result of a controller action. 15 | // This data is read and displayed by the _AlertPartial view 16 | public class WithAlertResult : IActionResult 17 | { 18 | public IActionResult Result { get; } 19 | 20 | public Alert Alert { get; } 21 | 22 | public WithAlertResult(IActionResult result, 23 | string type, 24 | string message, 25 | string debugInfo, 26 | string actionText, 27 | string actionUrl) 28 | { 29 | Result = result; 30 | Alert = new Alert 31 | { 32 | Type = type, 33 | Message = message, 34 | DebugInfo = debugInfo, 35 | ActionText = actionText, 36 | ActionUrl = actionUrl, 37 | }; 38 | } 39 | 40 | public async Task ExecuteResultAsync(ActionContext context) 41 | { 42 | var factory = context.HttpContext.RequestServices 43 | .GetService(); 44 | 45 | var tempData = factory.GetTempData(context.HttpContext); 46 | 47 | tempData.AddAlert("_alertData", Alert); 48 | 49 | await Result.ExecuteResultAsync(context); 50 | } 51 | } 52 | } 53 | // 54 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Groups/List.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model GroupsListDisplayModel 5 | 6 | @{ 7 | ViewData["Title"] = "List groups"; 8 | } 9 | 10 |
11 |
12 | 26 |
27 |
28 | Create group 29 |
30 |
31 | 32 |
33 |
34 | 35 |
36 |
37 | 38 |
39 |
40 | 41 |
42 |
43 | 44 |
45 |
-------------------------------------------------------------------------------- /SnippetsApp/Views/Calendar/_DailyEventsPartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | @model DailyViewModel 6 | 7 | @{ 8 | bool dateCellAdded = false; 9 | var timeFormat = User.GetUserGraphTimeFormat(); 10 | var rowClass = Model.Day.Date.Equals(DateTime.Today.Date) ? "table-warning" : ""; 11 | } 12 | 13 | @if (Model.Events.Count() <= 0) 14 | { 15 | // Render an empty row for the day 16 | 17 | 18 |
@Model.Day.Day
19 |
@Model.Day.ToString("dddd")
20 |
@Model.Day.ToString("MMMM, yyyy")
21 | 22 | 23 | 24 | 25 | } 26 | 27 | @foreach(var item in Model.Events) 28 | { 29 | 30 | @if (!dateCellAdded) 31 | { 32 | // Only add the day cell once 33 | dateCellAdded = true; 34 | 35 |
@Model.Day.Day
36 |
@Model.Day.ToString("dddd")
37 |
@Model.Day.ToString("MMMM, yyyy")
38 | 39 | } 40 | 41 |
@item.Start.ToString(timeFormat) - @item.End.ToString(timeFormat)
42 | 43 | 44 | 45 |
@item.Organizer
46 | 47 | 48 | } 49 | 50 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Calendar/New.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | @model NewEvent 6 | 7 | @{ 8 | ViewData["Title"] = "New event"; 9 | } 10 | 11 |
12 |
13 |
14 | 15 | 16 | 17 |
18 |
19 | 20 | 21 | 22 |
23 |
24 |
25 |
26 | 27 | 28 | 29 |
30 |
31 |
32 |
33 | 34 | 35 | 36 |
37 |
38 |
39 |
40 | 41 | 42 | 43 |
44 |
45 | 46 |
47 |
48 | 49 | @section Scripts { 50 | @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} 51 | } 52 | 53 | -------------------------------------------------------------------------------- /SnippetsApp/libman.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0", 3 | "defaultProvider": "cdnjs", 4 | "libraries": [ 5 | { 6 | "provider": "unpkg", 7 | "library": "bootstrap@4.5.0", 8 | "files": [ 9 | "LICENSE", 10 | "dist/css/bootstrap.css", 11 | "dist/css/bootstrap.css.map", 12 | "dist/css/bootstrap.min.css", 13 | "dist/css/bootstrap.min.css.map", 14 | "dist/css/bootstrap-grid.css", 15 | "dist/css/bootstrap-grid.css.map", 16 | "dist/css/bootstrap-grid.min.css", 17 | "dist/css/bootstrap-grid.min.css.map", 18 | "dist/css/bootstrap-reboot.css", 19 | "dist/css/bootstrap-reboot.css.map", 20 | "dist/css/bootstrap-reboot.min.css", 21 | "dist/css/bootstrap-reboot.min.css.map", 22 | "dist/js/bootstrap.bundle.js", 23 | "dist/js/bootstrap.bundle.js.map", 24 | "dist/js/bootstrap.bundle.min.js", 25 | "dist/js/bootstrap.bundle.min.js.map", 26 | "dist/js/bootstrap.js", 27 | "dist/js/bootstrap.js.map", 28 | "dist/js/bootstrap.min.js", 29 | "dist/js/bootstrap.min.js.map" 30 | ], 31 | "destination": "wwwroot/lib/bootstrap" 32 | }, 33 | { 34 | "library": "jquery@3.5.1", 35 | "files": [ 36 | "jquery.js", 37 | "jquery.min.js", 38 | "jquery.min.map" 39 | ], 40 | "destination": "wwwroot/lib/jquery/dist" 41 | }, 42 | { 43 | "library": "jquery-validate@1.19.2", 44 | "files": [ 45 | "additional-methods.js", 46 | "additional-methods.min.js", 47 | "jquery.validate.js", 48 | "jquery.validate.min.js" 49 | ], 50 | "destination": "wwwroot/lib/jquery-validation/dist" 51 | }, 52 | { 53 | "library": "jquery-validation-unobtrusive@3.2.11", 54 | "files": [ 55 | "jquery.validate.unobtrusive.js", 56 | "jquery.validate.unobtrusive.min.js" 57 | ], 58 | "destination": "wwwroot/lib/jquery-validation-unobtrusive" 59 | } 60 | ] 61 | } -------------------------------------------------------------------------------- /SnippetsApp/Views/Calendar/Display.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model Event 5 | 6 | @using Microsoft.Graph 7 | 8 | @{ 9 | ViewData["Title"] = Model.Subject; 10 | } 11 | 12 |
13 | 14 | 15 |
16 |
17 |
18 |

@(string.IsNullOrEmpty(Model.Subject) ? "(No subject)" : Model.Subject)

19 |
20 |
Organizer:
21 |
@Model.Organizer?.EmailAddress.Name
22 |
23 | @if (Model.Attendees?.Count() > 0) 24 | { 25 | 26 | } 27 | @if (Model.Location != null) 28 | { 29 |
30 |
Location:
31 |
@Model.Location.DisplayName
32 |
33 | } 34 | @if (Model.Attachments?.Count() > 0) 35 | { 36 |
37 |
Attachments:
38 |
39 | 40 |
41 |
42 | } 43 |
44 |
45 |
46 |
47 | @if (Model.IsOrganizer.Equals(true)) 48 | { 49 | 50 | } 51 | else 52 | { 53 | 54 | } 55 |
56 |
57 |
58 |
59 | @if (Model.Body.ContentType.Equals(BodyType.Html)) 60 | { 61 | @Html.Raw(Model.Body.Content) 62 | } 63 | else 64 | { 65 |

@Model.Body.Content

66 | } 67 |

68 |
-------------------------------------------------------------------------------- /SnippetsApp/Views/Users/Display.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model UserWithPhoto 5 | 6 | @{ 7 | ViewData["Title"] = Model.User.DisplayName; 8 | string email = User.IsPersonalAccount() ? 9 | Model.User.UserPrincipalName : Model.User.Mail; 10 | } 11 | 12 |
13 |
14 |
15 | 16 |
17 |
18 |
19 |

@Model.User.DisplayName

20 |

@email

21 |
22 | 23 |
24 | 25 |
26 | 27 |
28 | 29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | @if (Model.Manager != null) 38 | { 39 |
40 |
41 |

Manager

42 | 43 |
44 |
45 | } 46 | @if (Model.DirectReports != null && Model.DirectReports.Count > 0) 47 | { 48 |
49 |
50 |

Direct reports

51 | 52 |
53 |
54 | } 55 | -------------------------------------------------------------------------------- /SnippetsApp/Graph/GraphConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | namespace SnippetsApp 5 | { 6 | public static class GraphConstants 7 | { 8 | // Defines the permission scopes used by the app 9 | public readonly static string[] DefaultScopes = 10 | { 11 | UserReadWrite, 12 | MailboxSettingsRead 13 | }; 14 | 15 | // Default page size for collections 16 | public const int PageSize = 25; 17 | 18 | // User 19 | public const string UserRead = "User.Read"; 20 | public const string UserReadBasicAll = "User.ReadBasic.All"; 21 | public const string UserReadAll = "User.Read.All"; 22 | public const string UserReadWrite = "User.ReadWrite"; 23 | public const string UserReadWriteAll = "User.ReadWrite.All"; 24 | 25 | // Group 26 | public const string GroupReadWriteAll = "Group.ReadWrite.All"; 27 | 28 | // Teams 29 | public const string ChannelCreate = "Channel.Create"; 30 | public const string ChannelMessageSend = "ChannelMessage.Send"; 31 | public const string ChannelSettingsReadWriteAll = "ChannelSettings.ReadWrite.All"; 32 | public const string TeamsAppInstallationReadWriteForTeam = "TeamsAppInstallation.ReadWriteForTeam"; 33 | public const string TeamCreate = "Team.Create"; 34 | public const string TeamSettingsReadWriteAll = "TeamSettings.ReadWrite.All"; 35 | 36 | // Mailbox settings 37 | public const string MailboxSettingsRead = "MailboxSettings.Read"; 38 | 39 | // Mail 40 | public const string MailRead = "Mail.Read"; 41 | public const string MailReadWrite = "Mail.ReadWrite"; 42 | public const string MailSend = "Mail.Send"; 43 | 44 | // Calendar 45 | public const string CalendarReadWrite = "Calendars.ReadWrite"; 46 | 47 | // Files 48 | public const string FilesReadWrite = "Files.ReadWrite"; 49 | public const string FilesReadWriteAll = "Files.ReadWrite.All"; 50 | 51 | // Errors 52 | public const string ItemNotFound = "ErrorItemNotFound"; 53 | public const string RequestDenied = "Authorization_RequestDenied"; 54 | public const string RequestResourceNotFound = "Request_ResourceNotFound"; 55 | public const string ResourceNotFound = "ResourceNotFound"; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /SnippetsApp/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | for details on configuring this project to bundle and minify static web assets. */ 3 | 4 | a.navbar-brand { 5 | white-space: normal; 6 | text-align: center; 7 | word-break: break-all; 8 | } 9 | 10 | /* Provide sufficient contrast against white background */ 11 | a { 12 | color: #0366d6; 13 | } 14 | 15 | .btn-primary { 16 | color: #fff; 17 | background-color: #1b6ec2; 18 | border-color: #1861ac; 19 | } 20 | 21 | .nav-pills .nav-link.active, .nav-pills .show > .nav-link { 22 | color: #fff; 23 | background-color: #1b6ec2; 24 | border-color: #1861ac; 25 | } 26 | 27 | /* Sticky footer styles 28 | -------------------------------------------------- */ 29 | html { 30 | font-size: 14px; 31 | } 32 | @media (min-width: 768px) { 33 | html { 34 | font-size: 16px; 35 | } 36 | } 37 | 38 | .border-top { 39 | border-top: 1px solid #e5e5e5; 40 | } 41 | .border-bottom { 42 | border-bottom: 1px solid #e5e5e5; 43 | } 44 | 45 | .box-shadow { 46 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); 47 | } 48 | 49 | button.accept-policy { 50 | font-size: 1rem; 51 | line-height: inherit; 52 | } 53 | 54 | /* Sticky footer styles 55 | -------------------------------------------------- */ 56 | html { 57 | position: relative; 58 | min-height: 100%; 59 | } 60 | 61 | body { 62 | /* Margin bottom by footer height */ 63 | margin-bottom: 60px; 64 | } 65 | .footer { 66 | position: absolute; 67 | bottom: 0; 68 | width: 100%; 69 | white-space: nowrap; 70 | line-height: 60px; /* Vertically center the text there */ 71 | } 72 | 73 | /* */ 74 | .nav-profile-photo { 75 | width: 32px; 76 | } 77 | 78 | .alert-pre { 79 | word-wrap: break-word; 80 | word-break: break-all; 81 | white-space: pre-wrap; 82 | } 83 | 84 | .calendar-view-date-cell { 85 | width: 150px; 86 | } 87 | 88 | .calendar-view-date { 89 | width: 40px; 90 | font-size: 36px; 91 | line-height: 36px; 92 | margin-right: 10px; 93 | } 94 | 95 | .calendar-view-month { 96 | font-size: 0.75em; 97 | } 98 | 99 | .calendar-view-timespan { 100 | width: 200px; 101 | } 102 | 103 | .calendar-view-subject { 104 | font-size: 1.25em; 105 | } 106 | 107 | .calendar-view-organizer { 108 | font-size: .75em; 109 | } 110 | /* */ 111 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Groups/Display.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model GroupWithPhoto 5 | 6 | @{ 7 | ViewData["Title"] = Model.Group.DisplayName; 8 | string groupTypes = Model.Group.GroupTypes.Count() > 0 ? 9 | string.Join(",", Model.Group.GroupTypes) : 10 | "Security"; 11 | } 12 | 13 |
14 |
15 |
16 | 17 |
18 |
19 |
20 |

@Model.Group.DisplayName

21 | Group type: @groupTypes 22 |

@Model.Group.Description

23 |
24 | @if (Model.Group.MailEnabled.Equals(true)) 25 | { 26 | 27 | } 28 | else 29 | { 30 | 31 | } 32 | 33 |
34 |
35 | @if (Model.Group.SecurityEnabled.Equals(true)) 36 | { 37 | 38 | } 39 | else 40 | { 41 | 42 | } 43 | 44 |
45 |
46 | 47 |
48 | 49 |
50 | 51 |
52 | 53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
-------------------------------------------------------------------------------- /SnippetsApp/Views/Calendar/_AttendeeTimePartial.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model Event 5 | 6 | @using Microsoft.Graph 7 | 8 | @{ 9 | var start = DateTimeOffset.Parse(Model.Start.DateTime); 10 | var end = DateTimeOffset.Parse(Model.End.DateTime); 11 | var format = $"{User.GetUserGraphDateFormat()} {User.GetUserGraphTimeFormat()}"; 12 | string response = ""; 13 | switch(Model.ResponseStatus.Response) 14 | { 15 | case ResponseType.Accepted: 16 | response = "You accepted on "; 17 | break; 18 | case ResponseType.Declined: 19 | response = "You declined on "; 20 | break; 21 | case ResponseType.TentativelyAccepted: 22 | response = "You tentatively accepted on "; 23 | break; 24 | default: 25 | response = "You have not responded"; 26 | break; 27 | } 28 | } 29 | 30 |
31 |
Start:
32 |
@start.ToString(format)
33 |
34 |
35 |
End:
36 |
@end.ToString(format)
37 |
38 |
39 | @response 40 | @if (!Model.ResponseStatus.Response.Equals(ResponseType.NotResponded)) 41 | { 42 | 43 | } 44 |
45 | 46 | 47 |
48 |
49 |
50 |
51 | 52 |
53 | 54 | 55 |
56 |
57 | 58 | 59 |
60 | 61 | 62 | 63 |
64 |
65 |
66 |
67 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Files/Display.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model DriveItem 5 | 6 | @using Microsoft.Graph 7 | @using ByteSizeLib 8 | 9 | @{ 10 | ViewData["Title"] = Model.Name; 11 | string dateTimeFormat = $"{User.GetUserGraphDateFormat()} {User.GetUserGraphTimeFormat()}"; 12 | } 13 | 14 | Back 15 |
16 |
17 | 18 | 19 |
20 |
21 |
22 |
23 | 24 | 25 |
26 |
27 |
28 |
29 | 30 | 31 | 32 |
33 |
34 | 35 |
36 |
37 |
38 | 39 |
40 |
41 | 42 |
43 | 44 |
45 |
46 |
47 |
48 |
49 |
Size:
50 |
@ByteSize.FromBytes(Model.Size.Value).ToString()
51 |
52 |
53 |
Created by:
54 |
@Model.CreatedBy.User.DisplayName
55 |
56 |
57 |
Created on:
58 |
59 |
60 |
61 |
Last modified by:
62 |
@Model.LastModifiedBy.User.DisplayName
63 |
64 |
65 |
Last modified on:
66 |
67 |
68 |
69 |
-------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /SnippetsApp/Models/RoamingSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using Microsoft.Graph; 7 | 8 | namespace SnippetsApp.Models 9 | { 10 | public class RoamingSettings 11 | { 12 | // The extension name serves as the ID of the extension 13 | public static readonly string ExtensionName = "com.contoso.roamingSettings"; 14 | 15 | // The values this app uses 16 | public string Theme { get; set; } 17 | public string Color { get; set; } 18 | public string Language { get; set; } 19 | 20 | private RoamingSettings() {} 21 | 22 | public static RoamingSettings Create(string theme, string color, string language) 23 | { 24 | return new RoamingSettings 25 | { 26 | Theme = theme, 27 | Color = color, 28 | Language = language 29 | 30 | }; 31 | } 32 | 33 | public static RoamingSettings FromOpenExtension(Extension openExtension) 34 | { 35 | if (openExtension == null) 36 | { 37 | return null; 38 | } 39 | 40 | // Make sure this extension is the expected one 41 | // By using a fully-qualified name here using your company domain, 42 | // this should avoid conflicts in extensions with other apps 43 | if (string.Compare(openExtension.Id, RoamingSettings.ExtensionName, true) != 0) 44 | { 45 | throw new ArgumentException( 46 | $"The open extension provided is not of the required type. Expected: {RoamingSettings.ExtensionName}, Actual: {openExtension.Id}."); 47 | } 48 | 49 | return Create(GetValue("theme", openExtension), 50 | GetValue("color", openExtension), GetValue("language", openExtension)); 51 | } 52 | 53 | public OpenTypeExtension ToOpenExtension() 54 | { 55 | return new OpenTypeExtension 56 | { 57 | // Extension name is the only required property 58 | ExtensionName = RoamingSettings.ExtensionName, 59 | 60 | // Since this is an open type, developers must serialize 61 | // the data they use into a dictionary 62 | AdditionalData = new Dictionary 63 | { 64 | { "theme", Theme }, 65 | { "color", Color }, 66 | { "language", Language } 67 | } 68 | }; 69 | } 70 | 71 | // Helper function to get values out as strings from the dictionary 72 | private static string GetValue(string key, Extension openExtension) 73 | { 74 | object value; 75 | var hasValue = openExtension 76 | .AdditionalData.TryGetValue(key, out value); 77 | 78 | if (hasValue && value != null) 79 | { 80 | return value.ToString(); 81 | } 82 | 83 | return null; 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /SnippetsApp/Models/RoamingSettingsDisplayModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using Microsoft.AspNetCore.Mvc.Rendering; 6 | 7 | namespace SnippetsApp.Models 8 | { 9 | // Class used to simplify working with 24 | 25 | 26 | 27 | 28 |
29 |
30 | 31 | 32 | 33 | 34 |
35 |
36 |
37 |
38 | 39 | 40 | 41 |
42 |
43 | 44 |
45 |
46 |
47 |
Reply
48 |
49 | 50 | 51 |
52 | 53 | 54 |
55 | 56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
Reply all
64 |
65 | 66 | 67 |
68 | 69 | 70 |
71 | 72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
Forward
80 |
81 | 82 | 83 |
84 | 85 | 86 |
87 |
88 | 89 | 90 |
91 | 92 |
93 |
94 |
95 |
96 | 97 |
98 |
99 |

@(string.IsNullOrEmpty(Model.Subject) ? "(No subject)" : Model.Subject)

100 |
101 |
From:
102 |
@Model.From?.EmailAddress.Name
103 |
104 |
105 |
Received:
106 |
107 |
108 | @if (Model.ToRecipients?.Count() > 0) 109 | { 110 |
111 |
To:
112 |
113 | 114 |
115 |
116 | } 117 | @if (Model.CcRecipients?.Count() > 0) 118 | { 119 |
120 |
Cc:
121 |
122 | 123 |
124 |
125 | } 126 | @if (Model.Attachments?.Count() > 0) 127 | { 128 |
129 |
Attachments:
130 |
131 | 132 |
133 |
134 | } 135 |
136 |
137 |
138 |
139 | @if (Model.Body.ContentType.Equals(BodyType.Html)) 140 | { 141 | @Html.Raw(Model.Body.Content) 142 | } 143 | else 144 | { 145 |

@Model.Body.Content

146 | } 147 |

148 |
149 | 150 | @section Scripts 151 | { 152 | 172 | } 173 | -------------------------------------------------------------------------------- /SnippetsApp/Startup.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | using System.Net; 5 | using System.Net.Http.Headers; 6 | using System.Threading.Tasks; 7 | using Microsoft.AspNetCore.Authentication.OpenIdConnect; 8 | using Microsoft.AspNetCore.Authorization; 9 | using Microsoft.AspNetCore.Builder; 10 | using Microsoft.AspNetCore.Hosting; 11 | using Microsoft.AspNetCore.Mvc.Authorization; 12 | using Microsoft.Extensions.Configuration; 13 | using Microsoft.Extensions.DependencyInjection; 14 | using Microsoft.Extensions.Hosting; 15 | using Microsoft.Identity.Web; 16 | using Microsoft.Identity.Web.UI; 17 | using Microsoft.IdentityModel.Protocols.OpenIdConnect; 18 | using Microsoft.Graph; 19 | 20 | namespace SnippetsApp 21 | { 22 | public class Startup 23 | { 24 | public Startup(IConfiguration configuration) 25 | { 26 | Configuration = configuration; 27 | } 28 | 29 | public IConfiguration Configuration { get; } 30 | 31 | // This method gets called by the runtime. Use this method to add services to the container. 32 | public void ConfigureServices(IServiceCollection services) 33 | { 34 | // Add Microsoft Identity Platform sign-in 35 | services 36 | .AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) 37 | .AddMicrosoftIdentityWebApp(options => { 38 | Configuration.Bind("AzureAd", options); 39 | 40 | options.Prompt = "select_account"; 41 | 42 | options.Events.OnTokenValidated = async context => { 43 | var tokenAcquisition = context.HttpContext.RequestServices 44 | .GetRequiredService(); 45 | 46 | var graphClient = new GraphServiceClient( 47 | new DelegateAuthenticationProvider(async (request) => { 48 | var token = await tokenAcquisition 49 | .GetAccessTokenForUserAsync(GraphConstants.DefaultScopes, user:context.Principal); 50 | request.Headers.Authorization = 51 | new AuthenticationHeaderValue("Bearer", token); 52 | }) 53 | ); 54 | 55 | // Get user information from Graph 56 | var user = await graphClient.Me.Request() 57 | .Select(u => new { 58 | u.DisplayName, 59 | u.Mail, 60 | u.UserPrincipalName, 61 | u.MailboxSettings 62 | }) 63 | .GetAsync(); 64 | 65 | context.Principal.AddUserGraphInfo(user); 66 | 67 | if (context.Principal.IsPersonalAccount()) 68 | { 69 | // Personal accounts do not support getting their 70 | // photo via Graph 71 | // Support is there in the beta API 72 | context.Principal.AddUserGraphPhoto(null); 73 | return; 74 | } 75 | 76 | // Get the user's photo 77 | // If the user doesn't have a photo, this throws 78 | try 79 | { 80 | var photo = await graphClient.Me 81 | .Photos["48x48"] 82 | .Content 83 | .Request() 84 | .GetAsync(); 85 | 86 | context.Principal.AddUserGraphPhoto(photo); 87 | } 88 | catch (ServiceException ex) 89 | { 90 | if (ex.IsMatch("ErrorItemNotFound")) 91 | { 92 | context.Principal.AddUserGraphPhoto(null); 93 | } 94 | else 95 | { 96 | throw; 97 | } 98 | } 99 | }; 100 | 101 | options.Events.OnAuthenticationFailed = context => { 102 | var error = WebUtility.UrlEncode(context.Exception.Message); 103 | context.Response 104 | .Redirect($"/Home/ErrorWithMessage?message=Authentication+error&debug={error}"); 105 | context.HandleResponse(); 106 | 107 | return Task.FromResult(0); 108 | }; 109 | 110 | options.Events.OnRemoteFailure = context => { 111 | if (context.Failure is OpenIdConnectProtocolException) 112 | { 113 | var error = WebUtility.UrlEncode(context.Failure.Message); 114 | context.Response 115 | .Redirect($"/Home/ErrorWithMessage?message=Sign+in+error&debug={error}"); 116 | context.HandleResponse(); 117 | } 118 | 119 | return Task.FromResult(0); 120 | }; 121 | }) 122 | // Add ability to call web API (Graph) 123 | // and get access tokens 124 | .EnableTokenAcquisitionToCallDownstreamApi(options => { 125 | Configuration.Bind("AzureAd", options); 126 | }, GraphConstants.DefaultScopes) 127 | // Add a GraphServiceClient via dependency injection 128 | .AddMicrosoftGraph(options => { 129 | options.Scopes = string.Join(' ', GraphConstants.DefaultScopes); 130 | }) 131 | // Use in-memory token cache 132 | // See https://github.com/AzureAD/microsoft-identity-web/wiki/token-cache-serialization 133 | .AddInMemoryTokenCaches(); 134 | 135 | // Require authentication 136 | services.AddControllersWithViews(options => 137 | { 138 | var policy = new AuthorizationPolicyBuilder() 139 | .RequireAuthenticatedUser() 140 | .Build(); 141 | options.Filters.Add(new AuthorizeFilter(policy)); 142 | }) 143 | // Add the Microsoft Identity UI pages for signin/out 144 | .AddMicrosoftIdentityUI(); 145 | 146 | services.AddRazorPages() 147 | .AddRazorRuntimeCompilation(); 148 | } 149 | 150 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 151 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 152 | { 153 | if (env.IsDevelopment()) 154 | { 155 | app.UseDeveloperExceptionPage(); 156 | } 157 | else 158 | { 159 | app.UseExceptionHandler("/Home/Error"); 160 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 161 | app.UseHsts(); 162 | } 163 | app.UseHttpsRedirection(); 164 | app.UseStaticFiles(); 165 | 166 | app.UseRouting(); 167 | 168 | app.UseAuthentication(); 169 | app.UseAuthorization(); 170 | 171 | app.UseEndpoints(endpoints => 172 | { 173 | endpoints.MapControllerRoute( 174 | name: "default", 175 | pattern: "{controller=Home}/{action=Index}/{id?}"); 176 | }); 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /README-Localized/README-zh-tw.md: -------------------------------------------------------------------------------- 1 | # Microsoft Graph 程式碼片段範例 (適用於 ASP.NET 4.6) 2 | 3 | 4 | ## 目錄 5 | 6 | 7 | * [必要條件](#prerequisites) 8 | * [註冊應用程式](#register-the-application) 9 | * [建置及執行範例](#build-and-run-the-sample) 10 | * [附註的程式碼](#code-of-note) 11 | * [問題和建議](#questions-and-comments) 12 | * [參與](#contributing) 13 | * [其他資源](#additional-resources) 14 | 15 | 此範例提供程式碼片段的儲存機制,使用 Microsoft Graph 以執行一般工作,例如傳送郵件、管理群組及其他 ASP.NET MVC 應用程式內的活動。它會使用 [Microsoft Graph.NET 用戶端 SDK](https://github.com/microsoftgraph/msgraph-sdk-dotnet),使用 Microsoft Graph 所傳回的資料。 16 | 17 | 範例會使用 [Microsoft 驗證程式庫 (MSAL)](https://www.nuget.org/packages/Microsoft.Identity.Client/) 進行驗證。MSAL SDK 提供功能以使用 [Azure AD v2.0 端點](https://azure.microsoft.com/en-us/documentation/articles/active-directory-appmodel-v2-overview),可讓開發人員撰寫單一程式碼流程,控制工作或學校 (Azure Active Directory) 和個人 (Microsoft) 帳戶的驗證。 18 | 19 | 此外,此範例顯示如何以累加方式要求權杖 - Azure AD v2.0 端點所支援的功能。使用者在登入期間同意一組初始的權限範圍,但是稍後可以同意其他範圍。在這個範例中,任何有效的使用者都可以登入,但是系統管理員稍後可以同意特定作業所需的系統管理層級範圍。 20 | 21 | 本範例使用 [ASP.NET OpenId Connect OWIN 中介軟體](https://www.nuget.org/packages/Microsoft.Owin.Security.OpenIdConnect/),以及在初始權杖擷取期間使用。這個範例也會實作自訂的 Owin 中介軟體,交換登入流程外的存取和重新整理權杖的授權程式碼。自訂中介軟體會呼叫 MSAL 以建置授權要求 URI 並且處理重新導向。若要深入了解增量的同意,請參閱[使用 OpenID Connect 將 Microsoft 身分識別與 Microsoft Graph 整合至 Web 應用程式](https://github.com/Azure-Samples/active-directory-dotnet-webapp-openidconnect-v2)。 22 | 23 | ## MSAL 預覽相關的重要事項 24 | 25 | 26 | 這個程式庫適合在實際執行環境中使用。 我們為我們目前的實際執行程式庫提供與此程式庫相同的實際執行層級支援。 在預覽期間,我們可能會變更此程式庫的 API、內部快取格式和其他機制,您將必須對此程式庫進行錯誤修復或增強功能。 這可能會影響您的應用程式。 舉例來說,變更快取格式可能會影響您的使用者,例如需要使用者重新登入。 API 變更可能需要更新您的程式碼。 當我們提供「一般可用性」版本時,將要求您在六個月內更新至「一般可用性」版本,因為使用程式庫預覽版本所撰寫的應用程式可能無法運作。 27 | 28 | 29 | ## 必要條件 30 | 31 | 32 | 此範例需要下列項目: 33 | 34 | * [Visual Studio 2015](https://www.visualstudio.com/en-us/downloads) 35 | * [Microsoft 帳戶](https://www.outlook.com)或[ 商務用 Office 365 帳戶](https://msdn.microsoft.com/en-us/office/office365/howto/setup-development-environment#bk_Office365Account)。需要 Office 365 系統管理員帳戶,才能執行系統管理層級的作業。您可以註冊 [Office 365 開發人員訂用帳戶](https://msdn.microsoft.com/en-us/office/office365/howto/setup-development-environment#bk_Office365Account),其中包含開始建置應用程式所需的資源。 36 | 37 | ## 註冊應用程式 38 | 39 | 40 | 1. 使用您的個人或工作或學校帳戶登入[應用程式註冊入口網站](https://apps.dev.microsoft.com/)。 41 | 42 | 2. 選擇 [新增應用程式]****。 43 | 44 | 3. 為應用程式輸入名稱,然後選擇 [建立應用程式]****。 45 | 46 | [註冊] 頁面隨即顯示,列出您的應用程式的屬性。 47 | 48 | 4. 複製應用程式 ID。這是您的應用程式的唯一識別碼。 49 | 50 | 5. 在 [應用程式密碼]**** 底下,選擇 [產生新密碼]****。從 [產生的新密碼]**** 對話方塊中複製密碼。 51 | 52 | 您必須輸入您複製到範例應用程式的應用程式識別碼和應用程式密碼值。 53 | 54 | 6. 在 [平台]**** 底下,選擇 [新增平台]****。 55 | 56 | 7. 選擇 [Web]****。 57 | 58 | 8. 請確定已選取 [允許隱含的流程]**** 核取方塊,然後輸入 *https://localhost:44300/* 做為重新導向 URI。 59 | 60 | [允許隱含的流程]**** 選項會啟用混合式流程。在驗證期間,這可讓應用程式收到登入資訊 (id_token) 和成品 (在這種情況下,是授權程式碼),應用程式可以用來取得存取權杖。 61 | 62 | 9. 選擇 [儲存]****。 63 | 64 | 65 | ## 建置及執行範例 66 | 67 | 68 | 1. 下載或複製 Microsoft Graph 程式碼片段範例 (適用於 ASP.NET 4.6)。 69 | 70 | 2. 在 Visual Studio 中開啟範例解決方案。 71 | 72 | 3. 在根目錄的 Web.config 檔案中,將 **ida:AppId** 和 **ida:AppSecret** 預留位置值取代為您在應用程式註冊期間複製的值。 73 | 74 | 4. 按 F5 以建置及執行範例。這樣會還原 NuGet 封裝相依性,並開啟應用程式。 75 | 76 | >如果您在安裝封裝時看到任何錯誤,請確定您放置解決方案的本機路徑不會太長/太深。將解決方案移靠近您的磁碟機根目錄可解決這個問題。 77 | 78 | 5. 登入您的個人帳戶 (MSA) 或工作或學校帳戶,並授與要求的權限。 79 | 80 | 6. 選擇程式碼片段類別,例如使用者、檔案或郵件。 81 | 82 | 7. 選擇您想要執行的作業。注意下列事項: 83 | - 需要引數 (例如 ID) 的作業已停用,直到您執行程式碼片段,讓您選取實體。 84 | 85 | - 某些程式碼片段 (標示為*僅限系統管理員*) 需要商業權限範圍,只能由系統管理員授與。若要執行這些程式碼片段,您必須以系統管理員的身分登入,然後使用 [系統管理範圍]** 索引標籤上的連結,同意系統管理層級範圍。此索引標籤不適用於以個人帳戶登入的使用者。 86 | 87 | - 如果您使用個人帳戶登入,程式碼片段不受支援,因為 Microsoft 帳戶已停用.. 88 | 89 | 回應資訊會顯示在頁面底部。 90 | 91 | ### 範例如何影響帳戶資料 92 | 93 | 94 | 這個範例會建立、更新和刪除實體和資料 (例如使用者或檔案)。根據您使用它的方式,**您可能編輯或刪除實際的實體和資料**並保留資料成品。 95 | 96 | 若要使用範例,而不修改您的實際帳戶資料,請務必執行更新,並只刪除範例所建立的實體的作業。 97 | 98 | 99 | ## 附註的程式碼 100 | 101 | 102 | - [Startup.Auth.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/App_Start/Startup.Auth.cs).驗證目前使用者,並初始化範例的權杖快取。 103 | 104 | - [SessionTokenCache.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/TokenStorage/SessionTokenCache.cs).儲存使用者的權杖資訊。您可以將這個項目取代為您自己的自訂權杖快取。在[多租用戶應用程式中的快取存取權杖](https://azure.microsoft.com/en-us/documentation/articles/guidance-multitenant-identity-token-cache/)中深入了解。 105 | 106 | - [SampleAuthProvider.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Helpers/SampleAuthProvider.cs).實作本機 IAuthProvider 介面,並取得存取權杖,方法是使用 **AcquireTokenSilentAsync** 方法。您可以將這個項目取代為您自己的授權提供者。 107 | 108 | - [SDKHelper.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Helpers/SDKHelper.cs).從 **Microsoft Graph.NET 用戶端程式庫**初始化 [GraphServiceClient](https://github.com/microsoftgraph/msgraph-sdk-dotnet) 用來與 Microsoft Graph 互動。 109 | 110 | - 下列控制站包含方法,該方法使用 **GraphServiceClient** 以建置並傳送呼叫至 Microsoft Graph 服務,並且處理回應。 111 | - [UsersController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/UsersController.cs) 112 | - [MailController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/MailController.cs) 113 | - [EventsController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/EventsController.cs) 114 | - [FilesController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/FilesController.cs) 115 | - [GroupsController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/GroupsController.cs) 116 | 117 | - 下列檢視包含範例的 UI。 118 | - [Users.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Users/Users.cshtml) 119 | - [Mail.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Mail/Mail.cshtml) 120 | - [Events.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Events/Events.cshtml) 121 | - [Files.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Files/Files.cshtml) 122 | - [Groups.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Groups/Groups.cshtml) 123 | 124 | - 下列檔案包含檢視模型和部分檢視,用來剖析和顯示 Microsoft Graph 資料為泛型物件 (針對此範例的目的)。 125 | - [ResultsViewModel.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Models/ResultsViewModel.cs) 126 | - [_ResultsPartial.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Shared/_ResultsPartial.cshtml) 127 | 128 | - 下列檔案包含用來支援遞增同意的程式碼。在此範例中,系統會提示使用者在登入期間同意初始權限集,並單獨授予管理員權限。 129 | - [AdminController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/AdminController.cs) 130 | - [OAuth2CodeRedeemerMiddleware.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Utils/OAuth2CodeRedeemerMiddleware.cs)。自訂中介軟體,其可兌換授權碼以存取和重新整理登入流程之外的權杖。如需有關實作增量同意的詳細資訊,請參閱 https://github.com/Azure-Samples/active-directory-dotnet-webapp-openidconnect-v2。 131 | 132 | ## 問題和建議 133 | 134 | 135 | 我們很樂於收到您對於此範例的意見反應。您可以在此儲存機制的[問題](https://github.com/microsoftgraph/aspnet-snippets-sample/issues)區段中,將您的問題及建議傳送給我們。 136 | 137 | 我們很重視您的意見。請透過 [Stack Overflow](http://stackoverflow.com/questions/tagged/microsoftgraph) 與我們連絡。以 [MicrosoftGraph] 標記您的問題。 138 | 139 | ## 參與 140 | 141 | 142 | 如果您想要參與這個範例,請參閱 [CONTRIBUTING.md](CONTRIBUTING.md)。 143 | 144 | 此專案已採用 [Microsoft 開放原始碼執行](https://opensource.microsoft.com/codeofconduct/)。如需詳細資訊,請參閱[程式碼執行常見問題集](https://opensource.microsoft.com/codeofconduct/faq/),如果有其他問題或意見,請連絡 [opencode@microsoft.com](mailto:opencode@microsoft.com)。 145 | 146 | ## 其他資源 147 | 148 | 149 | - [其他 Microsoft Graph 程式碼片段範例](https://github.com/MicrosoftGraph?utf8=%E2%9C%93&query=snippets) 150 | - [Microsoft Graph 概觀](http://graph.microsoft.io) 151 | - [Office 開發人員程式碼範例](http://dev.office.com/code-samples) 152 | - [Office 開發人員中心](http://dev.office.com/) 153 | 154 | ## 著作權 155 | 156 | Copyright (c) 2016 Microsoft.著作權所有,並保留一切權利。 157 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_type: sample 3 | products: 4 | - office-365 5 | - office-onedrive 6 | - office-outlook 7 | - office-teams 8 | - m365 9 | - ms-graph 10 | languages: 11 | - csharp 12 | - aspx 13 | description: "This sample uses the Microsoft Graph .NET Client Library to work with data, and the Microsoft Identity Web for authentication on the Microsoft identity platform v2.0 endpoint." 14 | extensions: 15 | contentType: samples 16 | technologies: 17 | - Microsoft Graph 18 | - Microsoft identity platform 19 | services: 20 | - Office 365 21 | - OneDrive 22 | - Outlook 23 | - Groups 24 | - Microsoft identity platform 25 | - Microsoft Teams 26 | createdDate: 8/4/2016 10:31:51 AM 27 | --- 28 | # Microsoft Graph snippets sample for ASP.NET Core 3.1 29 | 30 | ## Table of contents 31 | 32 | - [Prerequisites](#prerequisites) 33 | - [Register the application](#register-the-application) 34 | - [Build and run the sample](#build-and-run-the-sample) 35 | - [Questions and comments](#questions-and-comments) 36 | - [Contributing](#contributing) 37 | - [Additional resources](#additional-resources) 38 | 39 | This sample project provides a repository of code snippets that use the Microsoft Graph to perform common tasks, such as sending email, managing groups, and other activities from within an ASP.NET Core MVC app. It uses the [Microsoft Graph .NET Client SDK](https://github.com/microsoftgraph/msgraph-sdk-dotnet) to work with data returned by the Microsoft Graph. 40 | 41 | The sample uses the [Microsoft Identity Web](https://github.com/AzureAD/microsoft-identity-web) library for authentication. This library provides features for working with the [Microsoft identity platform (v2.0)](https://docs.microsoft.com/azure/active-directory/develop/v2-overview), which enables developers to write a single auth flow that handles authentication for both work or school (Azure Active Directory) and personal (Microsoft) accounts. 42 | 43 | In addition, the sample shows how to request tokens incrementally. Users consent to an initial set of permission scopes during sign in, but can consent to other scopes later. In the case of this sample, any valid user can sign in, but admininstrators can later consent to the admin-level scopes required for certain operations. 44 | 45 | ## Important note about the Microsoft Identity Web preview 46 | 47 | The Microsoft Identity Web library is in preview. Please review the [support SLA](https://github.com/AzureAD/microsoft-identity-web#support-sla) before taking a dependency on this library in production code. 48 | 49 | ## Prerequisites 50 | 51 | This sample requires the following: 52 | 53 | - [.NET Core SDK](https://dotnet.microsoft.com/download) version 3.1 or later 54 | - A text editor to work with the code files. While you can use any editor, we recommend [Visual Studio Code](https://code.visualstudio.com/). This repository includes configuration files to enable debugging the sample in Visual Studio Code. 55 | - A Microsoft account (personal or work/school). If you don't have a Microsoft account, there are a couple of options to get a free account: 56 | - You can [sign up for a new personal Microsoft account](https://signup.live.com/signup?wa=wsignin1.0&rpsnv=12&ct=1454618383&rver=6.4.6456.0&wp=MBI_SSL_SHARED&wreply=https://mail.live.com/default.aspx&id=64855&cbcxt=mai&bk=1454618383&uiflavor=web&uaid=b213a65b4fdc484382b6622b3ecaa547&mkt=E-US&lc=1033&lic=1). 57 | - You can [sign up for the Office 365 Developer Program](https://developer.microsoft.com/office/dev-program) to get a free Office 365 subscription. 58 | 59 | ## Register the application 60 | 61 | 1. Open a browser and navigate to the [Azure Active Directory admin center](https://aad.portal.azure.com). Login using a **personal account** (aka: Microsoft Account) or **Work or School Account**. 62 | 63 | 1. Select **Azure Active Directory** in the left-hand navigation, then select **App registrations** under **Manage**. 64 | 65 | 1. Select **New registration**. On the **Register an application** page, set the values as follows. 66 | 67 | - Set **Name** to `ASP.NET Core Graph Snippets App`. 68 | - Set **Supported account types** to **Accounts in any organizational directory and personal Microsoft accounts**. 69 | - Under **Redirect URI**, set the first drop-down to `Web` and set the value to `https://localhost:5001/`. 70 | 71 | 1. Select **Register**. On the **ASP.NET Core Graph Snippets App** page, copy the value of the **Application (client) ID** and save it, you will need it in the next step. 72 | 73 | 1. Select **Authentication** under **Manage**. Under **Redirect URIs** add a URI with the value `https://localhost:5001/signin-oidc`. 74 | 75 | 1. Set the **Logout URL** to `https://localhost:5001/signout-oidc`. 76 | 77 | 1. Locate the **Implicit grant** section and enable **ID tokens**. Select **Save**. 78 | 79 | 1. Select **Certificates & secrets** under **Manage**. Select the **New client secret** button. Enter a value in **Description** and select one of the options for **Expires** and select **Add**. 80 | 81 | 1. Copy the client secret value before you leave this page. You will need it in the next step. 82 | 83 | > **IMPORTANT:** This client secret is never shown again, so make sure you copy it now. 84 | 85 | ## Build and run the sample 86 | 87 | 1. Open your command-line interface (CLI) in the **./SnippetsApp** directory and run the following command to restore dependencies. 88 | 89 | ```Shell 90 | dotnet restore 91 | ``` 92 | 93 | 1. Run the following commands to add your application ID and secret into the [.NET Secret Manager](https://docs.microsoft.com/aspnet/core/security/app-secrets). The Secret Manager is for development purposes only, production apps should use a trusted secret manager for storing secrets. Replace `YOUR_APP_ID` with your application ID, and `YOUR_APP_SECRET` with your application secret. 94 | 95 | ```Shell 96 | dotnet user-secrets init 97 | dotnet user-secrets set "AzureAd:ClientId" "YOUR_APP_ID" 98 | dotnet user-secrets set "AzureAd:ClientSecret" "YOUR_APP_SECRET" 99 | ``` 100 | 101 | 1. Run the sample: 102 | 103 | - From your CLI: `dotnet run` 104 | - From Visual Studio Code: Press **F5** or select the **Run** menu, then **Start Debugging**. 105 | 106 | 1. Sign in with your personal account (MSA) or your work or school account, and grant the requested permissions. 107 | 108 | 1. Choose a snippets category in the navigation bar, such as **Users**, **Files**, or **Mail**. 109 | 110 | > **NOTE:** If you logged in with a personal account, snippets that aren't supported for Microsoft accounts are removed from the navigation bar. 111 | 112 | ### How the sample affects your account data 113 | 114 | This sample creates, updates, and deletes entities and data (such as users or files). Depending on how you use it, **you might edit or delete actual entities and data** and leave data artifacts. 115 | 116 | To use the sample without modifying your actual account data, be sure to perform update and delete operations only on entities that are created by the sample. 117 | 118 | ## Questions and comments 119 | 120 | We'd love to get your feedback about this sample. You can send us your questions and suggestions in the [Issues](https://github.com/microsoftgraph/aspnet-snippets-sample/issues) section of this repository. 121 | 122 | Your feedback is important to us. Connect with us on [Stack Overflow](http://stackoverflow.com/questions/tagged/microsoftgraph). Tag your questions with [MicrosoftGraph]. 123 | 124 | ## Contributing 125 | 126 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 127 | 128 | ## Additional resources 129 | 130 | - [Microsoft Graph ASP.NET Core tutorial](https://docs.microsoft.com/graph/tutorials/aspnet-core) 131 | - [Microsoft Graph overview](https://docs.microsoft.com/graph/overview) 132 | - [Microsoft Graph API reference](https://docs.microsoft.com/graph/api/overview) 133 | 134 | ## Copyright 135 | 136 | Copyright (c) 2020 Microsoft. All rights reserved. 137 | -------------------------------------------------------------------------------- /README-Localized/README-zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_type: sample 3 | products: 4 | - office-365 5 | - office-outlook 6 | - ms-graph 7 | languages: 8 | - csharp 9 | - aspx 10 | description: "此示例使用 Microsoft Graph .NET 客户端库来处理数据,并使用 Microsoft 身份验证库 (MSAL) 在Azure AD v2.0 终结点上进行身份验证。" 11 | extensions: 12 | contentType: samples 13 | technologies: 14 | - Microsoft Graph 15 | services: 16 | - Office 365 17 | - Outlook 18 | - Groups 19 | createdDate: 8/4/2016 10:31:51 AM 20 | --- 21 | # 适用于 ASP.NET 4.6 的 Microsoft Graph 代码段示例 22 | 23 | ## 目录 24 | 25 | * [先决条件](#prerequisites) 26 | * [注册应用程序](#register-the-application) 27 | * [生成和运行示例](#build-and-run-the-sample) 28 | * [注释代码](#code-of-note) 29 | * [问题和意见](#questions-and-comments) 30 | * [参与](#contributing) 31 | * [其他资源](#additional-resources) 32 | 33 | 此示例项目提供使用 Microsoft Graph 执行常见任务的代码段存储库,例如发送电子邮件、管理组和 ASP.NET MVC 应用内的其他活动。它使用 [Microsoft Graph .NET Client SDK](https://github.com/microsoftgraph/msgraph-sdk-dotnet) 以结合使用由 Microsoft Graph 返回的数据。 34 | 35 | 此示例使用 [Microsoft 身份验证库 (MSAL)](https://www.nuget.org/packages/Microsoft.Identity.Client/) 进行身份验证。MSAL SDK 提供可使用 [Azure AD v2.0 终结点](https://azure.microsoft.com/en-us/documentation/articles/active-directory-appmodel-v2-overview)的功能,借助该终结点,开发人员可以编写单个代码流来处理对工作或学校 (Azure Active Directory) 帐户或个人 (Microsoft) 帐户的身份验证。 36 | 37 | 此外,该示例演示如何以增量方式请求令牌,这是受 Azure AD v2.0 终结点支持的功能。用户可在登录过程中同意一组初始权限范围,还可在稍后同意其他范围。在本示例中,任何有效的用户均可登录,但只有管理员可在稍后同意某些操作所需的管理员级别范围。 38 | 39 | 此示例在登录和初始令牌获取过程中使用 [ASP.NET OpenId Connect OWIN 中间件](https://www.nuget.org/packages/Microsoft.Owin.Security.OpenIdConnect/)。此示例还实现自定义 Owin 中间件来交换登录流之外的访问令牌和刷新令牌的授权代码。自定义中间件调用 MSAL 来生成授权请求 URI 并处理重定向。有关增量同意的详细信息,请参阅[使用 OpenID Connect 将 Microsoft 标识和 Microsoft Graph 集成到 Web 应用程序中](https://github.com/Azure-Samples/active-directory-dotnet-webapp-openidconnect-v2)。 40 | 41 | > 此示例使用 ASP.NET MVC 4.6。有关使用 ASP.NET Core 的示例,请参阅以下两个示例之一: - [ASP.NET Core 2.1 的 Microsoft Graph 连接示例](https://github.com/microsoftgraph/aspnetcore-connect-sample) - [使 Web 应用能够登录用户并使用 Microsoft 标识平台为开发人员调用 API](https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2) 42 | 43 | ## 有关 MSAL 预览版的重要说明 44 | 45 | 此库适用于生产环境。我们为此库提供的生产级支持与为当前生产库提供的支持相同。在预览期间,我们可能会更改 API、内部缓存格式和此库的其他机制,必须接受这些更改以及 bug 修复或功能改进。这可能会影响应用。例如,缓存格式更改可能会对用户造成影响,如要求用户重新登录。API 更改可能会要求更新代码。在我们提供通用版后,必须在 6 个月内更新到通用版,因为使用预览版库编写的应用可能不再可用。 46 | 47 | ## 先决条件 48 | 49 | 此示例要求如下: 50 | 51 | * [Visual Studio](https://www.visualstudio.com/en-us/downloads) 52 | * [Microsoft 帐户](https://www.outlook.com)或 [Office 365 商业版帐户](https://msdn.microsoft.com/en-us/office/office365/howto/setup-development-environment#bk_Office365Account)。需要 Office 365 管理员帐户才能运行管理员级别的操作。可以注册 [Office 365 开发人员订阅](https://msdn.microsoft.com/en-us/office/office365/howto/setup-development-environment#bk_Office365Account),其中包含开始生成应用所需的资源。 53 | 54 | ## 注册 Web 应用 55 | 56 | ### 选择要在其中创建应用程序的 Azure AD 租户 57 | 58 | 第一步需要执行以下操作: 59 | 60 | 1. 使用工作/学校帐户或 Microsoft 个人帐户登录到 [Azure 门户](https://portal.azure.com)。 61 | 1. 如果你的帐户存在于多个 Azure AD 租户中,请在页面顶部菜单的右上角选择你的配置文件,然后**切换目录**。将门户会话更改为所需的 Azure AD 租户。 62 | 63 | ### 注册应用 64 | 65 | 1. 导航到“面向开发人员的 Microsoft 标识平台”[应用注册](https://go.microsoft.com/fwlink/?linkid=2083908)页面。 66 | 1. 选择“新注册”****。 67 | 1. 出现“注册应用程序页”****后,输入应用程序的注册信息: 68 | - 在“名称”****部分输入一个会显示给应用用户的有意义的应用程序名称。 69 | - 将“受支持的帐户类型”****更改为“任何组织目录中的帐户和 Microsoft 个人帐户”(例如,Skype、Xbox、Outlook.com)****。 70 | > 请注意,有多个重定向 URI。成功创建应用后,稍后需要从“身份验证”****选项卡中添加这些更新。 71 | 1. 选择“注册”****以创建应用程序。 72 | 1. 在应用的“**概述**”页上,查找“**应用程序(客户端) ID**”值,并稍后记录下来。你将需要它来为此项目配置 Visual Studio 配置文件。 73 | 1. 在应用的“概览”页中,选择“身份验证”****部分。 74 | - 在“重定向 URI”部分中,选择组合框中的“Web”****,然后输入以下重定向 URI。 75 | - `https://localhost:44300/` 76 | - `https://localhost:44300/signin-oidc` 77 | - 在“高级设置****”部分,将“注销 URL”****设置为“https://localhost:44300/signout-oidc”`` 78 | - 在“高级设置**** | 隐式授予”****部分,请检查“ID 标记”****,因为此示例需要启用[隐式授予流](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow)以登录用户,并调用 API。 79 | 1. 选择“保存”****。 80 | 1. 在“证书 & 密钥”****页面的“客户端密钥”****部分中,选择“新建客户端密码”****: 81 | - 键入密钥说明(例如应用机密``), 82 | - 选择“1 年内”****、“2 年内”****或“永不过期”****的一个密钥持续时间。 83 | - 按“添加”****按钮时,将显示注册表项值。将值复制并保存在安全的位置。 84 | - 稍后将需要此密钥来配置 Visual Studio 中的项目。此键值将不再显示,任何其他方式也无法将其检索,因此在 Azure 门户中看到该键值后立即进行录制。 85 | 86 | ## 生成和运行示例 87 | 88 | 1. 下载或克隆适用于 ASP.NET 4.6 的 Microsoft Graph 代码段示例。 89 | 90 | 2. 在 Visual Studio 中打开示例解决方案。 91 | 92 | 3. 在根目录的 Web.config 文件中,使用你在应用注册过程中复制的值来替换 **ida:AppId** 和 **ida:AppSecret** 占位符值。 93 | 94 | 4. 按 F5 生成和运行此示例。这将还原 NuGet 包依赖项并打开该应用。 95 | 96 | >如果在安装包时出现任何错误,请确保你放置该解决方案的本地路径并未太长/太深。将解决方案移动到更接近驱动器根目录的位置可能可以解决此问题。 97 | 98 | 5. 使用你的个人帐户 (MSA)、工作或学校帐户登录,并授予所请求的权限。 99 | 100 | 6. 选择一个代码段类别,比如用户、文件或邮件。 101 | 102 | 7. 选择你想要运行的操作。请注意以下事项: 103 | - 在运行允许你选择实体的代码段之前,将禁用需要参数(如 ID)的操作。 104 | - 某些代码段(标记为 *仅管理员*)需要只能由管理员授予的商业权限范围。若要运行这些代码段,需要以管理员身份登录 Azure 门户。然后,使用应用注册中的“API 权限”**部分,以同意管理员级别的范围。此选项卡不适用于使用个人帐户登录的用户。 105 | - 如果你使用个人帐户登录,则会禁用 Microsoft 帐户不支持的代码段。 106 | 107 | 响应信息将在页面底部显示。 108 | 109 | ### 示例如何影响你的帐户数据 110 | 111 | 本示例创建、更新和删除实体和数据(如用户或文件)。具体取决于你使用本示例的方式,**可以编辑或删除实际的实体和数据**并保留数据项目。 112 | 113 | 若要在不修改实际帐户数据的情况下使用本示例,请确保仅在此示例创建的实体上执行更新和删除操作。 114 | 115 | 116 | ## 注释代码 117 | 118 | - [Startup.Auth.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/App_Start/Startup.Auth.cs)。对当前用户进行身份验证,并初始化此示例的令牌缓存。 119 | 120 | - [SessionTokenCache.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/TokenStorage/SessionTokenCache.cs)。存储用户的令牌信息。可以使用你自己的自定义令牌缓存来替换此信息。从[多租户应用程序中缓存访问令牌](https://azure.microsoft.com/en-us/documentation/articles/guidance-multitenant-identity-token-cache/)了解详细信息。 121 | 122 | - [SampleAuthProvider.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Helpers/SampleAuthProvider.cs)。实现本地 IAuthProvider 接口,并通过使用 **AcquireTokenSilentAsync** 方法获取一个访问令牌。可以使用你自己的授权提供程序来替换此方法。 123 | 124 | - [SDKHelper.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Helpers/SDKHelper.cs)。初始化来自用于与 Microsoft Graph 交互的 **Microsoft Graph .NET 客户端库**中的 [GraphServiceClient](https://github.com/microsoftgraph/msgraph-sdk-dotnet)。 125 | 126 | - 以下控制器包含使用 **GraphServiceClient** 生成调用并发送到 Microsoft Graph 服务并处理响应的方法。 127 | - [UsersController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/UsersController.cs) 128 | - [MailController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/MailController.cs) 129 | - [EventsController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/EventsController.cs) 130 | - [FilesController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/FilesController.cs) 131 | - [GroupsController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/GroupsController.cs) 132 | 133 | - 以下视图包含示例的 UI。 134 | - [Users.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Users/Users.cshtml) 135 | - [Mail.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Mail/Mail.cshtml) 136 | - [Events.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Events/Events.cshtml) 137 | - [Files.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Files/Files.cshtml) 138 | - [Groups.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Groups/Groups.cshtml) 139 | 140 | - 以下文件包含用于分析 Microsoft Graph 数据并将其显示为一般对象(出于本示例中的目的)的视图模型和分部视图。 141 | - [ResultsViewModel.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Models/ResultsViewModel.cs) 142 | - [\_ResultsPartial.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Shared/_ResultsPartial.cshtml) 143 | 144 | - 以下文件包含用于支持增量同意的代码。对于此示例,系统将分别提示用户同意登录期间的初始权限集和管理权限。 145 | - [AdminController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/AdminController.cs) 146 | - [OAuth2CodeRedeemerMiddleware.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Utils/OAuth2CodeRedeemerMiddleware.cs)。自定义中间件兑现登录流之外的访问令牌和刷新令牌的授权代码。有关实现增量同意的详细信息,请参阅 Https://github.com/Azure-Samples/active-directory-dotnet-webapp-openidconnect-v2。 147 | 148 | ## 问题和意见 149 | 150 | 我们乐意倾听你对此示例的反馈。你可以在该存储库中的[问题](https://github.com/microsoftgraph/aspnet-snippets-sample/issues)部分将问题和建议发送给我们。 151 | 152 | 我们非常重视你的反馈意见。请在[堆栈溢出](http://stackoverflow.com/questions/tagged/microsoftgraph)上与我们联系。使用 \[MicrosoftGraph] 标记出你的问题。 153 | 154 | ## 参与 155 | 156 | 如果想要参与本示例,请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。 157 | 158 | 此项目已采用 [Microsoft 开放源代码行为准则](https://opensource.microsoft.com/codeofconduct/)。有关详细信息,请参阅[行为准则常见问题解答](https://opensource.microsoft.com/codeofconduct/faq/)。如有其他任何问题或意见,也可联系 [opencode@microsoft.com](mailto:opencode@microsoft.com)。 159 | 160 | ## 其他资源 161 | 162 | - [其他 Microsoft Graph 代码段示例](https://github.com/MicrosoftGraph?utf8=%E2%9C%93&query=snippets) 163 | - [Microsoft Graph 概述](http://graph.microsoft.io) 164 | - [Office 开发人员代码示例](http://dev.office.com/code-samples) 165 | - [Office 开发人员中心](http://dev.office.com/) 166 | 167 | ## 版权信息 168 | 版权所有 (c) 2016 Microsoft。保留所有权利。 169 | -------------------------------------------------------------------------------- /SnippetsApp/Views/Teams/Display.cshtml: -------------------------------------------------------------------------------- 1 | 3 | 4 | @model TeamDisplayModel 5 | 6 | @using Microsoft.Graph 7 | 8 | @{ 9 | ViewData["Title"] = Model.Team.DisplayName; 10 | ViewData["teamId"] = Model.Team.Id; 11 | ViewData["teamArchived"] = Model.Team.IsArchived.Value; 12 | var archiveButtonLabel = Model.Team.IsArchived.Value ? "Unarchive" : "Archive"; 13 | } 14 | 15 |
16 |
17 |

@Model.Team.DisplayName

18 |
19 | 20 | 21 | 22 |
23 | 34 |
35 |
36 |
37 | 38 | 39 | 40 | 41 | 42 | 43 |
44 | 45 |
46 |
47 |
48 |
49 |
50 | 51 |
Messaging settings
52 |
53 | 54 | 55 | 56 |
57 |
58 | 59 | 60 | 61 |
62 |
63 | 64 | 65 | 66 |
67 |
68 | 69 | 70 | 71 |
72 |
73 | 74 | 75 | 76 |
77 |
78 |
Member settings
79 |
80 | 81 | 82 | 83 |
84 |
85 | 86 | 87 | 88 |
89 |
90 | 91 | 92 | 93 |
94 |
95 | 96 | 97 | 98 |
99 |
100 | 101 | 102 | 103 |
104 |
105 |
Guest settings
106 |
107 | 108 | 109 | 110 |
111 |
112 | 113 | 114 | 115 |
116 |
117 |
Fun settings
118 |
119 | 120 | 121 | 122 |
123 |
124 | 125 | 129 |
130 |
131 | 132 | 133 | 134 |
135 |
136 | 137 | 138 | 139 |
140 | 141 |
142 |
143 |
144 |
145 |
146 | 147 |
148 |
149 |
150 |
151 | -------------------------------------------------------------------------------- /README-Localized/README-ja-jp.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_type: sample 3 | products: 4 | - office-365 5 | - office-outlook 6 | - ms-graph 7 | languages: 8 | - csharp 9 | - aspx 10 | description: "このサンプルは、Microsoft Graph .NET クライアント ライブラリを使用してデータと連携し、Azure AD v2.0 での認証用に Microsoft Authentication Library (MSAL) を使用します。" 11 | extensions: 12 | contentType: samples 13 | technologies: 14 | - Microsoft Graph 15 | services: 16 | - Office 365 17 | - Outlook 18 | - Groups 19 | createdDate: 8/4/2016 10:31:51 AM 20 | --- 21 | # ASP.NET 4.6 用 Microsoft Graph スニペットのサンプル 22 | 23 | ## 目次 24 | 25 | * [前提条件](#prerequisites) 26 | * [アプリケーションの登録](#register-the-application) 27 | * [サンプルのビルドと実行](#build-and-run-the-sample) 28 | * [ノートのコード](#code-of-note) 29 | * [質問とコメント](#questions-and-comments) 30 | * [投稿](#contributing) 31 | * [追加情報](#additional-resources) 32 | 33 | このサンプル プロジェクトには、ASP.NET MVC アプリ内からのメール送信、グループ管理、および他のアクティビティなどの一般的なタスクを実行するために Microsoft Graph を使用する、コード スニペットのリポジトリが用意されています。[Microsoft Graph .NET クライアント SDK](https://github.com/microsoftgraph/msgraph-sdk-dotnet) を使用して、Microsoft Graph が返すデータを操作します。 34 | 35 | サンプルでは認証に [Microsoft 認証ライブラリ (MSAL)](https://www.nuget.org/packages/Microsoft.Identity.Client/) を使用します。MSAL SDK には、[Azure AD v2 0 エンドポイント](https://azure.microsoft.com/en-us/documentation/articles/active-directory-appmodel-v2-overview)を操作するための機能が用意されており、開発者は職場または学校 (Azure Active Directory) アカウント、および個人用 (Microsoft) アカウントの両方に対する認証を処理する 1 つのコード フローを記述することができます。 36 | 37 | またサンプルでは、トークンを段階的に要求する方法を示します。この方法は Azure AD v2.0 エンドポイントによってサポートされている機能です。ユーザーは、サインイン中にアクセス許可の適用範囲の最初のセットに同意することになりますが、後で他の適用範囲にも同意することができます。このサンプルの場合、すべての有効なユーザーがサインインできますが、管理者は後で特定の操作に必要な管理レベルの適用範囲に同意することができます。 38 | 39 | サンプルでは、サインインと最初のトークン取得中に [ASP.NET OpenId Connect OWIN ミドルウェア](https://www.nuget.org/packages/Microsoft.Owin.Security.OpenIdConnect/)を使用します。またサンプルでは、カスタム Owin ミドルウェアも実装して、アクセスの認証コードを交換し、サインイン フローの外部のトークンを更新します。カスタム ミドルウェアは、MSAL を呼び出して承認要求 URI を作成して、リダイレクトを処理します。段階的な同意の詳細については、「[OpenID Connect を使用して、Microsoft Identity と Microsoft Graph を Web アプリケーションに統合する](https://github.com/Azure-Samples/active-directory-dotnet-webapp-openidconnect-v2)」を参照してください。 40 | 41 | > このサンプルでは、ASP.NET MVC 4.6 を使用します。ASP.NET Core を使用するサンプルについては、次の 2 つのサンプルのいずれかを参照してください - [ASP.NET Core 2.1 用 Microsoft Graph Connect のサンプル](https://github.com/microsoftgraph/aspnetcore-connect-sample) - [開発者向けの Microsoft ID プラットフォームを使用して Web Apps でユーザーをサインインさせ API を呼び出せるようにする](https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2) 42 | 43 | ## MSAL プレビューに関する重要な注意事項 44 | 45 | このライブラリは、運用環境での使用に適しています。このライブラリに対しては、現在の運用ライブラリと同じ運用レベルのサポートを提供します。プレビュー中にこのライブラリの API、内部キャッシュの形式、および他のメカニズムを変更する場合があります。これは、バグの修正や機能強化の際に実行する必要があります。これは、アプリケーションに影響を与える場合があります。例えば、キャッシュ形式を変更すると、再度サインインが要求されるなどの影響をユーザーに与えます。API を変更すると、コードの更新が要求される場合があります。一般提供リリースが実施されると、プレビュー バージョンを使って作成されたアプリケーションは動作しなくなるため、6 か月以内に一般提供バージョンに更新することが求められます。 46 | 47 | ## 前提条件 48 | 49 | このサンプルを実行するには次のものが必要です。 50 | 51 | * [Visual Studio](https://www.visualstudio.com/en-us/downloads) 52 | * [Microsoft アカウント](https://www.outlook.com)または [Office 365 for Business アカウント](https://msdn.microsoft.com/en-us/office/office365/howto/setup-development-environment#bk_Office365Account)のいずれか。管理レベルの操作を実行するには、Office 365 の管理者アカウントが必要です。アプリのビルドを開始するために必要なリソースを含む、[Office 365 Developer サブスクリプション](https://msdn.microsoft.com/en-us/office/office365/howto/setup-development-environment#bk_Office365Account)にサインアップできます。 53 | 54 | ## Web アプリの登録 55 | 56 | ### アプリケーションを作成する Azure AD テナントの選択 57 | 58 | まず、次のことを行う必要があります。 59 | 60 | 1. 職場または学校のアカウントか、個人の Microsoft アカウントを使用して、[Azure portal](https://portal.azure.com)にサインインします。 61 | 1. ご利用のアカウントが複数の Azure AD テナントに存在する場合は、ページ上部のメニューの右上隅にあるプロフィールを選択してから、\[**ディレクトリの切り替え**]を選択します。ポータルのセッションを目的の Azure AD テナントに変更します。 62 | 63 | ### アプリの登録 64 | 65 | 1. 開発者向けの Microsoft ID プラットフォーム \[[アプリの登録](https://go.microsoft.com/fwlink/?linkid=2083908)] ページに移動します。 66 | 1. \[**新規登録**] を選択します。 67 | 1. \[**アプリケーションの登録ページ**] が表示されたら、以下のアプリケーションの登録情報を入力します。 68 | - \[**名前**] セクションに、アプリのユーザーに表示されるわかりやすいアプリケーション名を入力します。 69 | - \[**サポートされているアカウントの種類**] を \[**任意の組織のディレクトリ内のアカウントと個人用の Microsoft アカウント (例: Skype、Xbox、Outlook.com)**] に変更します。 70 | > 複数のリダイレクト URI があることに注意してください。アプリが正常に作成された後、\[**認証**] タブからそれらを追加する必要があります。 71 | 1. \[**登録**] を選択して、アプリケーションを作成します。 72 | 1. アプリの \[**概要**] ページで、\[**Application (client) ID**] (アプリケーション (クライアント) ID) の値を確認し、後で使用するために記録します。この情報は、このプロジェクトで Visual Studio 構成ファイルを設定するのに必要になります。 73 | 1. アプリの \[概要] ページで、\[**認証**] セクションを選択します。 74 | - \[リダイレクト URI] セクションで、コンボ ボックスの \[**Web**] を選択し、次のリダイレクト URI を入力します。 75 | - `https://localhost:44300/` 76 | - `https://localhost:44300/signin-oidc` 77 | - \[**詳細設定**] セクションの \[**ログアウト URL**] を「`https://localhost:44300/signout-oidc`」に設定します。 78 | - \[**詳細設定**] または \[**暗黙的な許可**] セクションで、このサンプルが[暗黙的な許可のフロー](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow)を有効にしてユーザーのサインインができるように、\[**ID トークン**] をチェック ボックスをオンにし、API を呼び出します。 79 | 1. \[**保存**] を選択します。 80 | 1. \[**証明書とシークレット**] ページの \[**クライアント シークレット**] セクションで、\[**新しいクライアント シークレット**]を選択します。 81 | - キーの説明を入力します (例 : `アプリ シークレット`)。 82 | - \[**1 年**]、\[**2 年**]、または \[**有効期限なし**] からキーの期間を選択します。 83 | - \[**追加**] ボタンを押すと、キー値が表示されます。値をコピーして安全な場所に保存します。 84 | - Visual Studio でプロジェクトを構成するには、このキーが必要になります。このキー値は二度と表示されず、他の方法で取得することもできませんので、Azure portal で表示されたらすぐに記録してください。 85 | 86 | ## サンプルのビルドと実行 87 | 88 | 1. ASP.NET 4.6 用 Microsoft Graph スニペットのサンプルをダウンロードするか、クローンを作成します。 89 | 90 | 2. Visual Studio でサンプル ソリューションを開きます。 91 | 92 | 3. ルート ディレクトリの Web.config ファイルで、**ida:AppId** と **ida:AppSecret** のプレースホルダ―の値をアプリの登録時にコピーした値と置き換えます。 93 | 94 | 4. F5 キーを押して、サンプルをビルドして実行します。これにより、NuGet パッケージの依存関係が復元され、アプリが開きます。 95 | 96 | >パッケージのインストール中にエラーが発生した場合は、ソリューションを保存したローカル パスが長すぎたり深すぎたりしていないかご確認ください。ドライブのルート近くにソリューションを移動すると問題が解決する場合があります。 97 | 98 | 5. 個人用アカウント (MSA) あるいは職場または学校アカウントでサインインし、要求されたアクセス許可を付与します。 99 | 100 | 6. ユーザー、ファイル、メールなどのスニペットのカテゴリを選択します。 101 | 102 | 7. 実行する操作を選択します。以下の点に注意してください: 103 | - 引数 (ID など) を必要とする操作は、エンティティを選択することができるスニペットを実行するまで無効になっています。 104 | - 一部のスニペット (*管理者のみ*としてマークされている) には、管理者だけが付与できる商用のアクセス許可の適用範囲が必要です。このスニペットを実行するには、管理者として Azure Portal にサインインする必要があります。次に、アプリの登録の \[*API のアクセス許可*] セクションを使用して、管理レベルの範囲に同意します。このタブは、個人用アカウントでログインしているユーザーに対しては使用できません。 105 | - 個人用アカウントでログインした場合は、Microsoft アカウントでサポートされていないスニペットは無効になっています。 106 | 107 | 応答情報は、ページの下部に表示されます。 108 | 109 | ### サンプルによるアカウント データへの影響 110 | 111 | このサンプルでは、エンティティとデータ (ユーザーまたはファイルなど) を作成、更新、および削除します。使用方法によっては、**実際のエンティティとデータを編集または削除して**、データの成果物をそのまま残す場合があります。 112 | 113 | 実際のアカウント データを変更せずにサンプルを使用するには、必ずサンプルで作成されるエンティティ上でのみ操作の更新と削除を実行します。 114 | 115 | 116 | ## ノートのコード 117 | 118 | - [Startup.Auth.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/App_Start/Startup.Auth.cs)。現在のユーザーを認証して、サンプルのトークン キャッシュを初期化します。 119 | 120 | - [SessionTokenCache.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/TokenStorage/SessionTokenCache.cs)。ユーザーのトークン情報を保存します。これを独自のカスタム トークン キャッシュと置き換えることができます。詳細については、「[マルチテナント アプリケーションのアクセス トークンのキャッシュ](https://azure.microsoft.com/en-us/documentation/articles/guidance-multitenant-identity-token-cache/)」を参照してください。 121 | 122 | - [SampleAuthProvider.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Helpers/SampleAuthProvider.cs)。ローカルの IAuthProvider インターフェイスを実装して、**AcquireTokenSilentAsync** メソッドを使用してアクセス トークンを取得します。これを独自の承認プロバイダーと置き換えることができます。 123 | 124 | - [SDKHelper.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Helpers/SDKHelper.cs)。Microsoft Graph との対話に使用される [Microsoft Graph .NET クライアント ライブラリ](https://github.com/microsoftgraph/msgraph-sdk-dotnet)の **GraphServiceClient** を初期化します。 125 | 126 | - 次のコントローラーには、呼び出しを構築して Microsoft Graph サービスに送信し、その応答を処理するために **GraphServiceClient** を使用するメソッドが含まれています。 127 | - [UsersController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/UsersController.cs) 128 | - [MailController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/MailController.cs) 129 | - [EventsController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/EventsController.cs) 130 | - [FilesController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/FilesController.cs) 131 | - [GroupsController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/GroupsController.cs) 132 | 133 | - 次のビューにはサンプルの UI が含まれています。 134 | - [Users.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Users/Users.cshtml) 135 | - [Mail.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Mail/Mail.cshtml) 136 | - [Events.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Events/Events.cshtml) 137 | - [Files.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Files/Files.cshtml) 138 | - [Groups.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Groups/Groups.cshtml) 139 | 140 | - 次のファイルには、汎用オブジェクトとして Microsoft Graph データを解析して表示する (このサンプルの目的用) ために使用されるビュー モデルと部分的なビューが含まれています。 141 | - [ResultsViewModel.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Models/ResultsViewModel.cs) 142 | - [\_ResultsPartial.cshtml](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Views/Shared/_ResultsPartial.cshtml) 143 | 144 | - 次のファイルには、段階的な同意をサポートするために使用されるコードが含まれています。このサンプルで、ユーザーはサインイン中にアクセス許可の初期セットへの同意を求められ、管理者アクセス許可への同意は別途求められます。 145 | - [AdminController.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Controllers/AdminController.cs) 146 | - [OAuth2CodeRedeemerMiddleware.cs](/Graph-ASPNET-46-Snippets/Microsoft%20Graph%20ASPNET%20Snippets/Utils/OAuth2CodeRedeemerMiddleware.cs)。アクセスの認証コードを使い、サインイン フローの外部のトークンを更新するカスタム ミドルウェアです。段階的な同意の実装の詳細については、https://github.com/Azure-Samples/active-directory-dotnet-webapp-openidconnect-v2 を参照してください。 147 | 148 | ## 質問とコメント 149 | 150 | このサンプルに関するフィードバックをお寄せください。質問や提案につきましては、このリポジトリの「[問題](https://github.com/microsoftgraph/aspnet-snippets-sample/issues)」セクションで送信できます。 151 | 152 | お客様からのフィードバックを重視しています。[スタック オーバーフロー](http://stackoverflow.com/questions/tagged/microsoftgraph)でご連絡ください。ご質問には \[MicrosoftGraph] のタグを付けてください。 153 | 154 | ## 投稿 155 | 156 | このサンプルに投稿する場合は、[CONTRIBUTING.md](CONTRIBUTING.md) を参照してください。 157 | 158 | このプロジェクトでは、[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) が採用されています。詳細については、「[Code of Conduct の FAQ](https://opensource.microsoft.com/codeofconduct/faq/)」を参照してください。また、その他の質問やコメントがあれば、[opencode@microsoft.com](mailto:opencode@microsoft.com) までお問い合わせください。 159 | 160 | ## 追加情報 161 | 162 | - [他の Microsoft Graph スニペットのサンプル](https://github.com/MicrosoftGraph?utf8=%E2%9C%93&query=snippets) 163 | - [Microsoft Graph の概要](http://graph.microsoft.io) 164 | - [Office 開発者向けコード サンプル](http://dev.office.com/code-samples) 165 | - [Office デベロッパー センター](http://dev.office.com/) 166 | 167 | ## 著作権 168 | Copyright (c) 2016 Microsoft.All rights reserved. 169 | --------------------------------------------------------------------------------