├── readme-images ├── copy_icon.png └── appId_and_redirectURI.png ├── Microsoft-Graph-Snippets-SDK ├── Assets │ ├── StoreLogo.png │ ├── SplashScreen.scale-100.png │ ├── SplashScreen.scale-200.png │ ├── LockScreenLogo.scale-200.png │ ├── Square44x44Logo.scale-200.png │ ├── Wide310x150Logo.scale-200.png │ ├── Square150x150Logo.scale-200.png │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ └── Resources.resw ├── excelTestResource.xlsx ├── LargeFileUploadResource.bmp ├── project.json ├── App.xaml ├── Properties │ ├── AssemblyInfo.cs │ └── Default.rd.xml ├── ViewModelBase.cs ├── Microsoft-Graph-Snippets-SDK.nuget.targets ├── ResultToBrushConverter.cs ├── Package.appxmanifest ├── StoryDefinition.cs ├── Microsoft-Graph-Snippets-SDK.nuget.props ├── Groups │ ├── GroupStories.cs │ └── GroupSnippets.cs ├── App.xaml.cs ├── MainPage.xaml ├── AuthenticationHelper.cs ├── Microsoft-Graph-Snippets-SDK.csproj ├── Users │ ├── UserStories.cs │ └── UserSnippets.cs └── MainPage.xaml.cs ├── LICENSE ├── Microsoft-Graph-Snippets-SDK.sln ├── .gitignore ├── README.md └── CONTRIBUTING.md /readme-images/copy_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-sample/HEAD/readme-images/copy_icon.png -------------------------------------------------------------------------------- /readme-images/appId_and_redirectURI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-sample/HEAD/readme-images/appId_and_redirectURI.png -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Assets/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-sample/HEAD/Microsoft-Graph-Snippets-SDK/Assets/StoreLogo.png -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/excelTestResource.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-sample/HEAD/Microsoft-Graph-Snippets-SDK/excelTestResource.xlsx -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/LargeFileUploadResource.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-sample/HEAD/Microsoft-Graph-Snippets-SDK/LargeFileUploadResource.bmp -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Assets/SplashScreen.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-sample/HEAD/Microsoft-Graph-Snippets-SDK/Assets/SplashScreen.scale-100.png -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-sample/HEAD/Microsoft-Graph-Snippets-SDK/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Assets/LockScreenLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-sample/HEAD/Microsoft-Graph-Snippets-SDK/Assets/LockScreenLogo.scale-200.png -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-sample/HEAD/Microsoft-Graph-Snippets-SDK/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-sample/HEAD/Microsoft-Graph-Snippets-SDK/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-sample/HEAD/Microsoft-Graph-Snippets-SDK/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Assets/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-sample/HEAD/Microsoft-Graph-Snippets-SDK/Assets/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "Microsoft.Graph": "1.4.0", 4 | "Microsoft.Identity.Client": "1.1.0-preview", 5 | "Microsoft.NETCore.UniversalWindowsPlatform": "5.3.1", 6 | "Newtonsoft.Json": "10.0.3" 7 | }, 8 | "frameworks": { 9 | "uap10.0": {} 10 | }, 11 | "runtimes": { 12 | "win10-arm": {}, 13 | "win10-arm-aot": {}, 14 | "win10-x86": {}, 15 | "win10-x86-aot": {}, 16 | "win10-x64": {}, 17 | "win10-x64-aot": {} 18 | } 19 | } -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/App.xaml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Office 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. 22 | 23 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("O365-UWP-Unified-API-Snippets")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("O365-UWP-Unified-API-Snippets")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Version information for an assembly consists of the following four values: 18 | // 19 | // Major Version 20 | // Minor Version 21 | // Build Number 22 | // Revision 23 | // 24 | // You can specify all the values or you can default the Build and Revision Numbers 25 | // by using the '*' as shown below: 26 | // [assembly: AssemblyVersion("1.0.*")] 27 | [assembly: AssemblyVersion("1.0.0.0")] 28 | [assembly: AssemblyFileVersion("1.0.0.0")] 29 | [assembly: ComVisible(false)] -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Properties/Default.rd.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/ViewModelBase.cs: -------------------------------------------------------------------------------- 1 | //Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. 2 | //See LICENSE in the project root for license information. 3 | 4 | using System; 5 | using System.ComponentModel; 6 | using System.Runtime.CompilerServices; 7 | 8 | namespace Microsoft_Graph_Snippets_SDK 9 | { 10 | /// 11 | /// Base view model for working with the unified API. 12 | /// 13 | public class ViewModelBase : INotifyPropertyChanged 14 | { 15 | 16 | protected bool SetProperty(ref T field, T value, [CallerMemberName] string propertyName = "") 17 | { 18 | // If the value is the same as the current value, return false to indicate this was a no-op. 19 | if (Object.Equals(field, value)) 20 | return false; 21 | 22 | // Raise any registered property changed events, and indicate to the user that the value was indeed changed. 23 | field = value; 24 | NotifyPropertyChanged(propertyName); 25 | return true; 26 | } 27 | 28 | public event PropertyChangedEventHandler PropertyChanged; 29 | 30 | 31 | protected void NotifyPropertyChanged([CallerMemberName]string propertyName = "") 32 | { 33 | if (PropertyChanged != null) 34 | PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Microsoft-Graph-Snippets-SDK.nuget.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/ResultToBrushConverter.cs: -------------------------------------------------------------------------------- 1 | //Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. 2 | //See LICENSE in the project root for license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using Windows.UI; 10 | using Windows.UI.Xaml.Data; 11 | using Windows.UI.Xaml.Media; 12 | 13 | namespace Microsoft_Graph_Snippets_SDK 14 | { 15 | /// 16 | /// Value converter that translates true to and false to 17 | /// . 18 | /// 19 | public sealed class ResultToBrushConverter : IValueConverter 20 | { 21 | private static readonly SolidColorBrush NOT_STARTED_BRUSH = new SolidColorBrush(Colors.LightSlateGray); 22 | private static readonly SolidColorBrush SUCCESS_BRUSH = new SolidColorBrush(Colors.Green); 23 | private static readonly SolidColorBrush FAILED_BRUSH = new SolidColorBrush(Colors.Red); 24 | public object Convert(object value, Type targetType, object parameter, string language) 25 | { 26 | bool? result = (bool?)value; 27 | if (result.HasValue) 28 | { 29 | return (result.Value) ? SUCCESS_BRUSH : FAILED_BRUSH; 30 | } 31 | else 32 | { 33 | return NOT_STARTED_BRUSH; 34 | } 35 | } 36 | 37 | public object ConvertBack(object value, Type targetType, object parameter, string language) 38 | { 39 | throw new NotImplementedException(); 40 | } 41 | } 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Package.appxmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | O365-UWP-Unified-API-Snippets 7 | jamescro 8 | Assets\StoreLogo.png 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/StoryDefinition.cs: -------------------------------------------------------------------------------- 1 | //Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. 2 | //See LICENSE in the project root for license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Microsoft_Graph_Snippets_SDK 11 | { 12 | 13 | //All of the properties of a story. 14 | public class StoryDefinition : ViewModelBase 15 | { 16 | //The name of the group to which the story belongs. 17 | public string GroupName { get; set; } 18 | //Display title of the story. 19 | public string Title { get; set; } 20 | 21 | //The permission scope group to which the story belongs. 22 | public string ScopeGroup { get; set; } 23 | 24 | // Delegate method to call. 25 | public Func> RunStoryAsync { get; set; } 26 | 27 | //Specifies whether the story is running. 28 | bool _isRunning = false; 29 | public bool IsRunning 30 | { 31 | get 32 | { 33 | return _isRunning; 34 | } 35 | set 36 | { 37 | SetProperty(ref _isRunning, value); 38 | } 39 | } 40 | 41 | //Success or failure result. 42 | bool? _result = null; 43 | public bool? Result 44 | { 45 | get 46 | { 47 | return _result; 48 | } 49 | set 50 | { 51 | SetProperty(ref _result, value); 52 | } 53 | } 54 | 55 | //Length of time the story takes to run. 56 | long? _durationMS = 0; 57 | public long? DurationMS 58 | { 59 | get 60 | { 61 | return _durationMS; 62 | } 63 | set 64 | { 65 | SetProperty(ref _durationMS, value); 66 | } 67 | } 68 | 69 | } 70 | 71 | 72 | } 73 | 74 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft-Graph-Snippets-SDK", "Microsoft-Graph-Snippets-SDK\Microsoft-Graph-Snippets-SDK.csproj", "{F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|ARM = Release|ARM 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Debug|ARM.ActiveCfg = Debug|ARM 19 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Debug|ARM.Build.0 = Debug|ARM 20 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Debug|ARM.Deploy.0 = Debug|ARM 21 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Debug|x64.ActiveCfg = Debug|x64 22 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Debug|x64.Build.0 = Debug|x64 23 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Debug|x64.Deploy.0 = Debug|x64 24 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Debug|x86.ActiveCfg = Debug|x86 25 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Debug|x86.Build.0 = Debug|x86 26 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Debug|x86.Deploy.0 = Debug|x86 27 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Release|ARM.ActiveCfg = Release|ARM 28 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Release|ARM.Build.0 = Release|ARM 29 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Release|ARM.Deploy.0 = Release|ARM 30 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Release|x64.ActiveCfg = Release|x64 31 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Release|x64.Build.0 = Release|x64 32 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Release|x64.Deploy.0 = Release|x64 33 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Release|x86.ActiveCfg = Release|x86 34 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Release|x86.Build.0 = Release|x86 35 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01}.Release|x86.Deploy.0 = Release|x86 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | EndGlobal 41 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Microsoft-Graph-Snippets-SDK.nuget.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | True 5 | NuGet 6 | C:\Users\jamescro\Documents\msal\uwp-csharp-snippets-sample\Microsoft-Graph-Snippets-SDK\project.lock.json 7 | $(UserProfile)\.nuget\packages\ 8 | C:\Users\jamescro\.nuget\packages\ 9 | ProjectJson 10 | 4.2.0 11 | 12 | 13 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studo 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | *_i.c 42 | *_p.c 43 | *_i.h 44 | *.ilk 45 | *.meta 46 | *.obj 47 | *.pch 48 | *.pdb 49 | *.pgc 50 | *.pgd 51 | *.rsp 52 | *.sbr 53 | *.tlb 54 | *.tli 55 | *.tlh 56 | *.tmp 57 | *.tmp_proj 58 | *.log 59 | *.vspscc 60 | *.vssscc 61 | .builds 62 | *.pidb 63 | *.svclog 64 | *.scc 65 | 66 | # Chutzpah Test files 67 | _Chutzpah* 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | *.cachefile 76 | 77 | # Visual Studio profiler 78 | *.psess 79 | *.vsp 80 | *.vspx 81 | 82 | # TFS 2012 Local Workspace 83 | $tf/ 84 | 85 | # Guidance Automation Toolkit 86 | *.gpState 87 | 88 | # ReSharper is a .NET coding add-in 89 | _ReSharper*/ 90 | *.[Rr]e[Ss]harper 91 | *.DotSettings.user 92 | 93 | # JustCode is a .NET coding addin-in 94 | .JustCode 95 | 96 | # TeamCity is a build add-in 97 | _TeamCity* 98 | 99 | # DotCover is a Code Coverage Tool 100 | *.dotCover 101 | 102 | # NCrunch 103 | _NCrunch_* 104 | .*crunch*.local.xml 105 | 106 | # MightyMoose 107 | *.mm.* 108 | AutoTest.Net/ 109 | 110 | # Web workbench (sass) 111 | .sass-cache/ 112 | 113 | # Installshield output folder 114 | [Ee]xpress/ 115 | 116 | # DocProject is a documentation generator add-in 117 | DocProject/buildhelp/ 118 | DocProject/Help/*.HxT 119 | DocProject/Help/*.HxC 120 | DocProject/Help/*.hhc 121 | DocProject/Help/*.hhk 122 | DocProject/Help/*.hhp 123 | DocProject/Help/Html2 124 | DocProject/Help/html 125 | 126 | # Click-Once directory 127 | publish/ 128 | 129 | # Publish Web Output 130 | *.[Pp]ublish.xml 131 | *.azurePubxml 132 | # TODO: Comment the next line if you want to checkin your web deploy settings 133 | # but database connection strings (with potential passwords) will be unencrypted 134 | *.pubxml 135 | *.publishproj 136 | 137 | # NuGet Packages 138 | *.nupkg 139 | # The packages folder can be ignored because of Package Restore 140 | **/packages/* 141 | # except build/, which is used as an MSBuild target. 142 | !**/packages/build/ 143 | # Uncomment if necessary however generally it will be regenerated when needed 144 | #!**/packages/repositories.config 145 | 146 | # Windows Azure Build Output 147 | csx/ 148 | *.build.csdef 149 | 150 | # Windows Store app package directory 151 | AppPackages/ 152 | 153 | # Others 154 | *.[Cc]ache 155 | ClientBin/ 156 | [Ss]tyle[Cc]op.* 157 | ~$* 158 | *~ 159 | *.dbmdl 160 | *.dbproj.schemaview 161 | *.pfx 162 | *.publishsettings 163 | node_modules/ 164 | bower_components/ 165 | 166 | # RIA/Silverlight projects 167 | Generated_Code/ 168 | 169 | # Backup & report files from converting an old project file 170 | # to a newer Visual Studio version. Backup files are not needed, 171 | # because we have git ;-) 172 | _UpgradeReport_Files/ 173 | Backup*/ 174 | UpgradeLog*.XML 175 | UpgradeLog*.htm 176 | 177 | # SQL Server files 178 | *.mdf 179 | *.ldf 180 | 181 | # Business Intelligence projects 182 | *.rdl.data 183 | *.bim.layout 184 | *.bim_*.settings 185 | 186 | # Microsoft Fakes 187 | FakesAssemblies/ 188 | 189 | # Node.js Tools for Visual Studio 190 | .ntvs_analysis.dat 191 | 192 | # Visual Studio 6 build log 193 | *.plg 194 | 195 | # Visual Studio 6 workspace options file 196 | *.opt 197 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Groups/GroupStories.cs: -------------------------------------------------------------------------------- 1 | //Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. 2 | //See LICENSE in the project root for license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using Windows.Storage; 10 | 11 | 12 | // NOTE: All groups snippets work only with admin work accounts. 13 | 14 | 15 | namespace Microsoft_Graph_Snippets_SDK 16 | { 17 | class GroupStories 18 | { 19 | 20 | private static readonly string STORY_DATA_IDENTIFIER = Guid.NewGuid().ToString(); 21 | 22 | public static async Task TryGetGroupsAsync() 23 | { 24 | var groups = await GroupSnippets.GetGroupsAsync(); 25 | return groups != null; 26 | } 27 | 28 | public static async Task TryGetGroupAsync() 29 | { 30 | var groups = await GroupSnippets.GetGroupsAsync(); 31 | 32 | // Create new group if no group currently exists 33 | // And then get updated groups array 34 | if (groups.Count == 0) { 35 | await GroupSnippets.CreateGroupAsync(STORY_DATA_IDENTIFIER); 36 | groups = await GroupSnippets.GetGroupsAsync(); 37 | }; 38 | 39 | //Pass the first group id from the list 40 | var groupId = groups[0].Id; 41 | var groupName = await GroupSnippets.GetGroupAsync(groupId); 42 | return groupName != null; 43 | } 44 | 45 | public static async Task TryGetGroupMembersAsync() 46 | { 47 | // Get all groups 48 | var groups = await GroupSnippets.GetGroupsAsync(); 49 | 50 | // Create new group if no group currently exists 51 | // And then get updated groups array 52 | if (groups.Count == 0) 53 | { 54 | await GroupSnippets.CreateGroupAsync(STORY_DATA_IDENTIFIER); 55 | groups = await GroupSnippets.GetGroupsAsync(); 56 | }; 57 | 58 | // Pass the first group id from the list 59 | var groupId = groups[0].Id; 60 | var members = await GroupSnippets.GetGroupMembersAsync(groupId); 61 | return members != null; 62 | } 63 | 64 | public static async Task TryGetGroupOwnersAsync() 65 | { 66 | // Get all groups 67 | var groups = await GroupSnippets.GetGroupsAsync(); 68 | 69 | // Create new group if no group currently exists 70 | // And then get updated groups array 71 | if (groups.Count == 0) 72 | { 73 | await GroupSnippets.CreateGroupAsync(STORY_DATA_IDENTIFIER); 74 | groups = await GroupSnippets.GetGroupsAsync(); 75 | }; 76 | 77 | // Pass the first group id from the list 78 | var groupId = groups[0].Id; 79 | var members = await GroupSnippets.GetGroupOwnersAsync(groupId); 80 | return members != null; 81 | } 82 | 83 | public static async Task TryCreateGroupAsync() 84 | { 85 | string createdGroup = await GroupSnippets.CreateGroupAsync(STORY_DATA_IDENTIFIER); 86 | return createdGroup != null; 87 | } 88 | 89 | public static async Task TryUpdateGroupAsync() 90 | { 91 | // Create an group first, then update it. 92 | string createdGroup = await GroupSnippets.CreateGroupAsync(STORY_DATA_IDENTIFIER); 93 | return await GroupSnippets.UpdateGroupAsync(createdGroup); 94 | } 95 | 96 | public static async Task TryDeleteGroupAsync() 97 | { 98 | // Create a group first, then delete it. 99 | string createdGroup = await GroupSnippets.CreateGroupAsync(STORY_DATA_IDENTIFIER); 100 | return await GroupSnippets.DeleteGroupAsync(createdGroup); 101 | } 102 | 103 | public static async Task TryAddUserToGroup() 104 | { 105 | //Create a group 106 | string createdGroup = await GroupSnippets.CreateGroupAsync(STORY_DATA_IDENTIFIER); 107 | //Create a user 108 | string createdUser = await UserSnippets.CreateUserAsync(STORY_DATA_IDENTIFIER); 109 | //Add the user to the group 110 | return await GroupSnippets.AddUserToGroup(createdUser, createdGroup); 111 | } 112 | } 113 | } 114 | 115 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/App.xaml.cs: -------------------------------------------------------------------------------- 1 | //Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. 2 | //See LICENSE in the project root for license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Runtime.InteropServices.WindowsRuntime; 9 | using Windows.ApplicationModel; 10 | using Windows.ApplicationModel.Activation; 11 | using Windows.Foundation; 12 | using Windows.Foundation.Collections; 13 | using Windows.UI.Xaml; 14 | using Windows.UI.Xaml.Controls; 15 | using Windows.UI.Xaml.Controls.Primitives; 16 | using Windows.UI.Xaml.Data; 17 | using Windows.UI.Xaml.Input; 18 | using Windows.UI.Xaml.Media; 19 | using Windows.UI.Xaml.Navigation; 20 | 21 | namespace Microsoft_Graph_Snippets_SDK 22 | { 23 | /// 24 | /// Provides application-specific behavior to supplement the default Application class. 25 | /// 26 | sealed partial class App : Application 27 | { 28 | /// 29 | /// Initializes the singleton application object. This is the first line of authored code 30 | /// executed, and as such is the logical equivalent of main() or WinMain(). 31 | /// 32 | public App() 33 | { 34 | this.InitializeComponent(); 35 | this.Suspending += OnSuspending; 36 | } 37 | 38 | /// 39 | /// Invoked when the application is launched normally by the end user. Other entry points 40 | /// will be used such as when the application is launched to open a specific file. 41 | /// 42 | /// Details about the launch request and process. 43 | protected override void OnLaunched(LaunchActivatedEventArgs e) 44 | { 45 | 46 | #if DEBUG 47 | if (System.Diagnostics.Debugger.IsAttached) 48 | { 49 | this.DebugSettings.EnableFrameRateCounter = true; 50 | } 51 | #endif 52 | 53 | Frame rootFrame = Window.Current.Content as Frame; 54 | 55 | // Do not repeat app initialization when the Window already has content, 56 | // just ensure that the window is active 57 | if (rootFrame == null) 58 | { 59 | // Create a Frame to act as the navigation context and navigate to the first page 60 | rootFrame = new Frame(); 61 | 62 | rootFrame.NavigationFailed += OnNavigationFailed; 63 | 64 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) 65 | { 66 | //TODO: Load state from previously suspended application 67 | } 68 | 69 | // Place the frame in the current Window 70 | Window.Current.Content = rootFrame; 71 | } 72 | 73 | if (rootFrame.Content == null) 74 | { 75 | // When the navigation stack isn't restored navigate to the first page, 76 | // configuring the new page by passing required information as a navigation 77 | // parameter 78 | rootFrame.Navigate(typeof(MainPage), e.Arguments); 79 | } 80 | // Ensure the current window is active 81 | Window.Current.Activate(); 82 | } 83 | 84 | /// 85 | /// Invoked when Navigation to a certain page fails 86 | /// 87 | /// The Frame which failed navigation 88 | /// Details about the navigation failure 89 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e) 90 | { 91 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName); 92 | } 93 | 94 | /// 95 | /// Invoked when application execution is being suspended. Application state is saved 96 | /// without knowing whether the application will be terminated or resumed with the contents 97 | /// of memory still intact. 98 | /// 99 | /// The source of the suspend request. 100 | /// Details about the suspend request. 101 | private void OnSuspending(object sender, SuspendingEventArgs e) 102 | { 103 | var deferral = e.SuspendingOperation.GetDeferral(); 104 | //TODO: Save application state and stop any background activity 105 | deferral.Complete(); 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/MainPage.xaml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 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 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/AuthenticationHelper.cs: -------------------------------------------------------------------------------- 1 | //Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. 2 | //See LICENSE in the project root for license information. 3 | 4 | using Microsoft.Graph; 5 | using System; 6 | using System.Diagnostics; 7 | using System.Net.Http; 8 | using System.Linq; 9 | using System.Net.Http.Headers; 10 | using System.Threading.Tasks; 11 | using Windows.Security.Authentication.Web; 12 | using Windows.Security.Authentication.Web.Core; 13 | using Windows.Security.Credentials; 14 | using Windows.Storage; 15 | using Microsoft.Identity.Client; 16 | 17 | namespace Microsoft_Graph_Snippets_SDK 18 | { 19 | internal static class AuthenticationHelper 20 | { 21 | // The Client ID is used by the application to uniquely identify itself to Microsoft Azure Active Directory (AD). 22 | static string clientId = App.Current.Resources["ida:ClientID"].ToString(); 23 | static string returnUrl = App.Current.Resources["ida:ReturnUrl"].ToString(); 24 | 25 | 26 | public static PublicClientApplication IdentityClientApp = null; 27 | public static string TokenForUser = null; 28 | public static DateTimeOffset expiration; 29 | 30 | private static GraphServiceClient graphClient = null; 31 | 32 | // Get an access token for the given context and resourceId. An attempt is first made to 33 | // acquire the token silently. If that fails, then we try to acquire the token by prompting the user. 34 | public static GraphServiceClient GetAuthenticatedClient() 35 | { 36 | if (graphClient == null) 37 | { 38 | // Create Microsoft Graph client. 39 | try 40 | { 41 | graphClient = new GraphServiceClient( 42 | "https://graph.microsoft.com/v1.0", 43 | new DelegateAuthenticationProvider( 44 | async (requestMessage) => 45 | { 46 | var token = await GetTokenForUserAsync(); 47 | requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token); 48 | // This header has been added to identify our sample in the Microsoft Graph service. If extracting this code for your project please remove. 49 | requestMessage.Headers.Add("SampleID", "uwp-csharp-snippets-sample"); 50 | 51 | })); 52 | return graphClient; 53 | } 54 | 55 | catch (Exception ex) 56 | { 57 | Debug.WriteLine("Could not create a graph client: " + ex.Message); 58 | } 59 | } 60 | 61 | return graphClient; 62 | } 63 | 64 | 65 | /// 66 | /// Get Token for User. 67 | /// 68 | /// Token for user. 69 | public static async Task GetTokenForUserAsync() 70 | { 71 | if (TokenForUser == null || expiration <= DateTimeOffset.UtcNow.AddMinutes(5)) 72 | { 73 | var redirectUri = new Uri(returnUrl); 74 | var scopes = new string[] 75 | { 76 | "https://graph.microsoft.com/User.Read", 77 | "https://graph.microsoft.com/User.ReadWrite", 78 | "https://graph.microsoft.com/User.ReadBasic.All", 79 | "https://graph.microsoft.com/Mail.Send", 80 | "https://graph.microsoft.com/Calendars.ReadWrite", 81 | "https://graph.microsoft.com/Mail.ReadWrite", 82 | "https://graph.microsoft.com/Files.ReadWrite", 83 | 84 | // Admin-only scopes. Uncomment these if you're running the sample with an admin work account. 85 | // You won't be able to sign in with a non-admin work account if you request these scopes. 86 | // These scopes will be ignored if you leave them uncommented and run the sample with a consumer account. 87 | // See the MainPage.xaml.cs file for all of the operations that won't work if you're not running the 88 | // sample with an admin work account. 89 | //"https://graph.microsoft.com/Directory.AccessAsUser.All", 90 | //"https://graph.microsoft.com/User.ReadWrite.All", 91 | //"https://graph.microsoft.com/Group.ReadWrite.All" 92 | 93 | 94 | }; 95 | 96 | IdentityClientApp = new PublicClientApplication(clientId); 97 | AuthenticationResult authResult = await IdentityClientApp.AcquireTokenAsync(scopes); 98 | 99 | TokenForUser = authResult.AccessToken; 100 | expiration = authResult.ExpiresOn; 101 | } 102 | 103 | return TokenForUser; 104 | } 105 | 106 | 107 | /// 108 | /// Signs the user out of the service. 109 | /// 110 | public static void SignOut() 111 | { 112 | foreach (var user in IdentityClientApp.Users) 113 | { 114 | IdentityClientApp.Remove(user); 115 | } 116 | graphClient = null; 117 | TokenForUser = null; 118 | 119 | } 120 | 121 | 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Microsoft-Graph-Snippets-SDK.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | x86 7 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01} 8 | AppContainerExe 9 | Properties 10 | Microsoft_Graph_Snippets_SDK 11 | Microsoft-Graph-Snippets-SDK 12 | en-US 13 | UAP 14 | 10.0.10240.0 15 | 10.0.10240.0 16 | 14 17 | true 18 | 512 19 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 20 | Microsoft-Graph-Snippets-SDK_TemporaryKey.pfx 21 | 22 | 23 | true 24 | bin\ARM\Debug\ 25 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 26 | ;2008 27 | full 28 | ARM 29 | false 30 | prompt 31 | true 32 | 33 | 34 | bin\ARM\Release\ 35 | TRACE;NETFX_CORE;WINDOWS_UWP 36 | true 37 | ;2008 38 | pdbonly 39 | ARM 40 | false 41 | prompt 42 | true 43 | true 44 | 45 | 46 | true 47 | bin\x64\Debug\ 48 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 49 | ;2008 50 | full 51 | x64 52 | false 53 | prompt 54 | true 55 | 56 | 57 | bin\x64\Release\ 58 | TRACE;NETFX_CORE;WINDOWS_UWP 59 | true 60 | ;2008 61 | pdbonly 62 | x64 63 | false 64 | prompt 65 | true 66 | true 67 | 68 | 69 | true 70 | bin\x86\Debug\ 71 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 72 | ;2008 73 | full 74 | x86 75 | false 76 | prompt 77 | true 78 | 79 | 80 | bin\x86\Release\ 81 | TRACE;NETFX_CORE;WINDOWS_UWP 82 | true 83 | ;2008 84 | pdbonly 85 | x86 86 | false 87 | prompt 88 | true 89 | true 90 | 91 | 92 | 93 | 94 | Always 95 | 96 | 97 | 98 | Always 99 | 100 | 101 | 102 | 103 | 104 | App.xaml 105 | 106 | 107 | 108 | 109 | 110 | MainPage.xaml 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | Designer 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | MSBuild:Compile 138 | Designer 139 | 140 | 141 | MSBuild:Compile 142 | Designer 143 | 144 | 145 | 146 | 147 | 14.0 148 | 149 | 150 | 157 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Groups/GroupSnippets.cs: -------------------------------------------------------------------------------- 1 | //Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. 2 | //See LICENSE in the project root for license information. 3 | 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Diagnostics; 8 | using System.Threading.Tasks; 9 | using Microsoft.Graph; 10 | 11 | // NOTE: All groups snippets work only with admin work accounts. 12 | 13 | 14 | namespace Microsoft_Graph_Snippets_SDK 15 | { 16 | class GroupSnippets 17 | { 18 | 19 | // Returns all of the groups in your tenant's directory. 20 | public static async Task GetGroupsAsync() 21 | { 22 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 23 | 24 | try 25 | { 26 | 27 | var groups = await graphClient.Groups.Request().GetAsync(); 28 | 29 | foreach (var group in groups ) 30 | { 31 | 32 | Debug.WriteLine("Got group: " + group.DisplayName); 33 | } 34 | 35 | return groups; 36 | 37 | } 38 | 39 | catch (ServiceException e) 40 | { 41 | Debug.WriteLine("We could not get groups: " + e.Error.Message); 42 | return null; 43 | } 44 | 45 | } 46 | 47 | 48 | // Returns the display name of a specific group. 49 | public static async Task GetGroupAsync(string groupId) 50 | { 51 | string groupName = null; 52 | //JObject jResult = null; 53 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 54 | try 55 | { 56 | var group = await graphClient.Groups[groupId].Request().GetAsync(); 57 | groupName = group.DisplayName; 58 | Debug.WriteLine("Got group: " + groupName); 59 | 60 | } 61 | 62 | 63 | catch (ServiceException e) 64 | { 65 | Debug.WriteLine("We could not get the specified group: " + e.Error.Message); 66 | return null; 67 | 68 | } 69 | 70 | return groupName; 71 | } 72 | 73 | public static async Task GetGroupMembersAsync(string groupId) 74 | { 75 | IGroupMembersCollectionWithReferencesPage members = null; 76 | 77 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 78 | 79 | try 80 | { 81 | var group = await graphClient.Groups[groupId].Members.Request().GetAsync(); 82 | members = group.Members; 83 | 84 | 85 | foreach (var member in members) 86 | { 87 | Debug.WriteLine("Member Id:" + member.Id); 88 | 89 | } 90 | 91 | } 92 | 93 | catch (ServiceException e) 94 | { 95 | Debug.WriteLine("We could not get the group members: " + e.Error.Message); 96 | return null; 97 | } 98 | 99 | return members; 100 | 101 | } 102 | 103 | public static async Task GetGroupOwnersAsync(string groupId) 104 | { 105 | IGroupOwnersCollectionWithReferencesPage owners = null; 106 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 107 | 108 | try 109 | { 110 | 111 | var group = await graphClient.Groups[groupId].Owners.Request().GetAsync(); 112 | owners = group.Owners; 113 | 114 | foreach (var owner in owners) 115 | { 116 | Debug.WriteLine("Owner Id:" + owner.Id); 117 | } 118 | 119 | } 120 | 121 | catch (ServiceException e) 122 | { 123 | Debug.WriteLine("We could not get the group owners: " + e.Error.Message); 124 | return null; 125 | } 126 | 127 | return owners; 128 | 129 | } 130 | 131 | 132 | // Creates a new group in the tenant. 133 | public static async Task CreateGroupAsync(string groupName) 134 | { 135 | //JObject jResult = null; 136 | string createdGroupId = null; 137 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 138 | 139 | 140 | try 141 | { 142 | var group = await graphClient.Groups.Request().AddAsync(new Group 143 | { 144 | GroupTypes = new List { "Unified" }, 145 | DisplayName = groupName, 146 | Description = "This group was created by the snippets app.", 147 | MailNickname = groupName, 148 | MailEnabled = false, 149 | SecurityEnabled = false 150 | }); 151 | 152 | createdGroupId = group.Id; 153 | 154 | Debug.WriteLine("Created group:" + createdGroupId); 155 | 156 | } 157 | 158 | catch (ServiceException e) 159 | { 160 | Debug.WriteLine("We could not create a group: " + e.Error.Message); 161 | return null; 162 | } 163 | 164 | return createdGroupId; 165 | 166 | } 167 | 168 | 169 | // Updates the description of an existing group. 170 | public static async Task UpdateGroupAsync(string groupId) 171 | { 172 | bool groupUpdated = false; 173 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 174 | 175 | try 176 | { 177 | var groupToUpdate = new Group(); 178 | groupToUpdate.Description = "This group was updated by the snippets app."; 179 | 180 | //The underlying REST call returns a 204 (no content), so we can't retrieve the updated group 181 | //with this call. 182 | await graphClient.Groups[groupId].Request().UpdateAsync(groupToUpdate); 183 | Debug.WriteLine("Updated group:" + groupId); 184 | groupUpdated = true; 185 | 186 | } 187 | 188 | catch (ServiceException e) 189 | { 190 | Debug.WriteLine("We could not update the group: " + e.Error.Message); 191 | groupUpdated = false; 192 | } 193 | 194 | return groupUpdated; 195 | 196 | } 197 | 198 | 199 | // Deletes an existing group in the tenant. 200 | public static async Task DeleteGroupAsync(string groupId) 201 | { 202 | bool eventDeleted = false; 203 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 204 | 205 | try 206 | { 207 | var groupToDelete = await graphClient.Groups[groupId].Request().GetAsync(); 208 | await graphClient.Groups[groupId].Request().DeleteAsync(); 209 | Debug.WriteLine("Deleted group:" + groupToDelete.Id); 210 | eventDeleted = true; 211 | 212 | } 213 | 214 | catch (ServiceException e) 215 | { 216 | Debug.WriteLine("We could not delete the group: " + e.Error.Message); 217 | eventDeleted = false; 218 | } 219 | 220 | return eventDeleted; 221 | 222 | } 223 | 224 | public static async Task AddUserToGroup(string userId, string groupId) 225 | { 226 | bool userAdded = false; 227 | GraphServiceClient graphClient = AuthenticationHelper.GetAuthenticatedClient(); 228 | 229 | try 230 | { 231 | User userToAdd = new User { Id = userId }; 232 | 233 | //The underlying REST call returns a 204 (no content), so we can't retrieve the updated group 234 | //with this call. 235 | await graphClient.Groups[groupId].Members.References.Request().AddAsync(userToAdd); 236 | Debug.WriteLine("Added user " + userId + " to the group: " + groupId); 237 | userAdded = true; 238 | 239 | } 240 | 241 | catch (ServiceException e) 242 | { 243 | Debug.WriteLine("We could not add a user to the group: " + e.Error.Message); 244 | userAdded = false; 245 | } 246 | return userAdded; 247 | } 248 | 249 | } 250 | } 251 | 252 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [ARCHIVED] Microsoft Graph UWP Snippets Sample (SDK) 2 | 3 | ## IMPORTANT 4 | 5 | **This project is being archived and replaced with the [Build UWP apps with Microsoft Graph](https://github.com/microsoftgraph/msgraph-training-uwp). As part of the archival process, we're closing all open issues and pull requests.** 6 | 7 | **You can continue to use this sample "as-is", but it won't be maintained moving forward. We apologize for any inconvenience.** 8 | 9 | **Table of contents** 10 | 11 | * [Introduction](#introduction) 12 | * [Prerequisites](#prerequisites) 13 | * [Register and configure the app](#register) 14 | * [Build and debug](#build) 15 | * [Run the sample](#run) 16 | * [How the sample affects your tenant data](#how-the-sample-affects-your-tenant-data) 17 | * [Add a snippet](#add-a-snippet) 18 | * [Questions and comments](#questions) 19 | * [Additional resources](#additional-resources) 20 | 21 | 22 | ## Introduction 23 | 24 | This sample contains a repository of code snippets that show how to use the Microsoft Graph SDK to send email, manage groups, and perform other activities with Office 365 data. It uses the [Microsoft Graph .NET Client Library](https://github.com/microsoftgraph/msgraph-sdk-dotnet) to work with data returned by Microsoft Graph. 25 | 26 | This repository shows you how to access multiple resources, including Microsoft Azure Active Directory (AD) and the Office 365 APIs, by making HTTP requests to the Microsoft Graph API in a Windows 10 universal app. 27 | 28 | In addition, the sample uses the [Microsoft Authentication Library (MSAL)](https://www.nuget.org/packages/Microsoft.Identity.Client/) for authentication. The MSAL SDK provides features for working with the [Azure AD v2.0 endpoint](https://msdn.microsoft.com/en-us/office/office365/howto/authenticate-Office-365-APIs-using-v2), which enables developers to write a single code flow that handles authentication for both users' work or school (Azure Active Directory) or personal (Microsoft) accounts. 29 | 30 | ## Important Note about the MSAL Preview 31 | 32 | This library is suitable for use in a production environment. We provide the same production level support for this library as we do our current production libraries. During the preview we may make changes to the API, internal cache format, and other mechanisms of this library, which you will be required to take along with bug fixes or feature improvements. This may impact your application. For instance, a change to the cache format may impact your users, such as requiring them to sign in again. An API change may require you to update your code. When we provide the General Availability release we will require you to update to the General Availability version within six months, as applications written using a preview version of library may no longer work. 33 | 34 | These snippets are simple and self-contained, and you can copy and paste them into your own code, whenever appropriate, or use them as a resource for learning how to use the Microsoft Graph client library. 35 | 36 | **Note:** If possible, please use this sample with a "non-work" or test account. The sample does not always clean up the created objects in your mailbox and calendar. At this time you'll have to manually remove sample mails and calendar events. Also note that the snippets that get and send messages and that get, create, update, and delete events won't work with all personal accounts. These operations will eventually work when those accounts are updated to work with the Azure AD v2.0 endpoint. 37 | 38 | 39 | 40 | 41 | ## Prerequisites ## 42 | 43 | This sample requires the following: 44 | 45 | * [Visual Studio 2015](https://www.visualstudio.com/en-us/downloads) 46 | * Windows 10 ([development mode enabled](https://msdn.microsoft.com/library/windows/apps/xaml/dn706236.aspx)) 47 | * Windows 10 SDK 48 | * Either a [Microsoft](www.outlook.com) or [Office 365 for business account](https://msdn.microsoft.com/en-us/office/office365/howto/setup-development-environment#bk_Office365Account). 49 | 50 | 51 | 52 | ## Register and configure the app 53 | 54 | 1. Sign into the [App Registration Portal](https://apps.dev.microsoft.com/) using either your personal or work or school account. 55 | 2. Select **Add an app**. 56 | 3. Enter a name for the app, and select **Create application**. The registration page displays, listing the properties of your app. 57 | 4. Under **Platforms**, select **Add platform**. 58 | 5. Select **Native Application**. 59 | 6. Copy both the Client Id (App Id) and Redirect URI values to the clipboard. You'll need to enter these values into the sample app. The app id is a unique identifier for your app. The redirect URI is a unique URI provided by Windows 10 for each application to ensure that messages sent to that URI are only sent to that application. 60 | 7. Select **Save**. 61 | 62 | 63 | 64 | ## Build and debug ## 65 | 66 | **Note:** If you see any errors while installing packages during step 2, make sure the local path where you placed the solution is not too long/deep. Moving the solution closer to the root of your drive resolves this issue. 67 | 68 | 1. After you've loaded the solution in Visual Studio, configure the sample to use the client id and redirectURI that you registered by adding the corresponding values for these keys in the Application.Resources node of the App.xaml file. 69 | ![Office 365 UWP Microsoft Graph connect sample](/readme-images/appId_and_redirectURI.png "Client ID value in App.xaml file")` 70 | 71 | 2. If you are planning on signing into the sample with a work or school account that does not have admin permissions, you'll need to leave code that requests scopes requiring admin permissions commented out. If these lines aren't commented, you won't be able to sign in with your non-admin work or school account (if you sign in with a personal account, these scope requests are ignored.) 72 | 73 | In the `GetTokenForUserAsync()` method of the `AuthenticationHelper.cs` file, see the following scope requests. Leave these commented unless you're using a work or school account that has admin permissions: 74 | 75 | ``` 76 | //"https://graph.microsoft.com/Directory.AccessAsUser.All", 77 | //"https://graph.microsoft.com/User.ReadWrite.All", 78 | //"https://graph.microsoft.com/Group.ReadWrite.All", 79 | ``` 80 | 81 | 3. Press F5 to build and debug. Run the solution and sign in with either your personal or work or school account. 82 | 83 | 84 | ## Run the sample 85 | 86 | When launched, the app displays a series of boxes representing common user tasks, or 'stories'. Each story is comprised of one or more code snippets. The stories are grouped by the account type and permission level: 87 | 88 | - Tasks that are applicable to both work or school and personal accounts, such as getting and sending email, creating files, etc. 89 | - Tasks that are only applicable to work or school accounts, such as getting a user's manager or account photo. 90 | - Tasks that are only applicable to a work or school account with administrative permissions, such as getting group members or creating new user accounts. 91 | 92 | Select the stories you want to execute, and choose the run button. You'll be prompted to log in with your work or school or personal account. Be aware that if you log in with an account that doesn't have applicable permissions for the stories you've selected(for example, if you select stories that are applicable only to a work or school account, and then log in with a personal account), those stories will fail. 93 | 94 | Each story turns green if it succeeds, and red if it fails. Additional information is sent to the Output window. Select **Ctrl + W,O** to view the Output window and see information about the operation. 95 | 96 | 97 | ##How the sample affects your tenant data 98 | This sample runs commands that create, read, update, or delete data. When running commands that delete or edit data, the sample creates test entities. The sample will leave behind some of these entities on your tenant. 99 | 100 | 101 | ##Add a snippet 102 | 103 | This project includes two snippets files: 104 | 105 | - Groups\GroupSnippets.cs 106 | - Users\UserSnippets.cs. 107 | 108 | If you have a snippet of your own that you would like to run in this project, just follow these three steps: 109 | 110 | 1. **Add your snippet to the snippets file.** Be sure to include a try/catch block. 111 | 112 | ```cs 113 | try 114 | { 115 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 116 | 117 | var currentUserObject = await graphClient.Me.Request().GetAsync(); 118 | currentUserName = currentUserObject.DisplayName; 119 | 120 | if ( currentUserName != null) 121 | { 122 | Debug.WriteLine("Got user: " + currentUserName); 123 | } 124 | 125 | } 126 | 127 | catch (ServiceException e) 128 | { 129 | Debug.WriteLine("We could not get the current user: " + e.Error.Message); 130 | return null; 131 | } 132 | ``` 133 | 134 | 2. **Create a story that uses your snippet and add it to the associated stories file.** For example, the `TryGetMeAsync()` story uses the `GetMeAsync()` snippet inside the Users\UserStories.cs file: 135 | 136 | ```cs 137 | public static async Task TryGetMeAsync() 138 | { 139 | var currentUser = await UserSnippets.GetMeAsync(); 140 | 141 | return currentUser != null; 142 | } 143 | ``` 144 | 145 | Sometimes your story will need to run snippets in addition to the one that you're implementing. For example, if you want to update an event, you can use the `CreateEventAsync()` method to create an event. Then you can update it. Always be sure to use snippets that already exist in the snippets file. If the operation you need doesn't exist, you'll have to create it and then include it in your story. It's a best practice to delete any entities that you create in a story, especially if you're working on anything other than a test or developer tenant. 146 | 147 | 3. **Add your story to the story collection in MainPageXaml.cs** (inside the `CreateStoryList()` method): 148 | 149 | ```cs 150 | StoryCollection.Add(new StoryDefinition() 151 | { GroupName = "Users", Title = "Get Me", 152 | ScopeGroup= "Applicable to personal or work accounts", RunStoryAsync = UserStories.TryGetMeAsync }); 153 | ``` 154 | 155 | Now you can test your snippet. When you run the app, your snippet will appear as a new box in the grid. Select the box for your snippet, and then run it. Use this as an opportunity to debug your snippet. 156 | 157 | 158 | ## Contributing ## 159 | 160 | If you'd like to contribute to this sample, see [CONTRIBUTING.MD](/CONTRIBUTING.md). 161 | 162 | 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. 163 | 164 | 165 | ## Questions and comments 166 | 167 | We'd love to get your feedback about the Microsoft Graph UWP Snippets Library project. You can send your questions and suggestions to us in the [Issues](https://github.com/OfficeDev/Microsoft-Graph-UWP-Snippets-Library/issues) section of this repository. 168 | 169 | Your feedback is important to us. Connect with us on [Stack Overflow](http://stackoverflow.com/questions/tagged/office365+or+microsoftgraph). Tag your questions with [MicrosoftGraph]. 170 | 171 | 172 | ## Additional resources ## 173 | 174 | - [Microsoft Graph overview](http://graph.microsoft.io) 175 | - [Office developer code samples](http://dev.office.com/code-samples) 176 | - [Office dev center](http://dev.office.com/) 177 | 178 | 179 | ## Copyright 180 | Copyright (c) 2016 Microsoft. All rights reserved. 181 | 182 | 183 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Assets/Resources.resw: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 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 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Accept a Meeting 122 | 123 | 124 | Add member 125 | 126 | 127 | Used Range 128 | 129 | 130 | Add Table Row 131 | 132 | 133 | Number Format 134 | 135 | 136 | clear selection 137 | 138 | 139 | Create Event 140 | 141 | 142 | Create Folder 143 | 144 | 145 | Create Group 146 | 147 | 148 | Create Text File 149 | 150 | 151 | Create User 152 | 153 | 154 | Create XL Chart 155 | 156 | 157 | Delete Event 158 | 159 | 160 | Delete File 161 | 162 | 163 | Delete Group 164 | 165 | 166 | Delete File 167 | 168 | 169 | disconnect 170 | 171 | 172 | Download File 173 | 174 | 175 | Excel snippets (work accounts only) 176 | 177 | 178 | Filter Table 179 | 180 | 181 | Some text content. 182 | 183 | 184 | Get a Group 185 | 186 | 187 | Get All Groups 188 | 189 | 190 | Get Directs 191 | 192 | 193 | Get Drive 194 | 195 | 196 | Get Events 197 | 198 | 199 | Get Manager 200 | 201 | 202 | Get Me 203 | 204 | 205 | Get Members 206 | 207 | 208 | Get Messages 209 | 210 | 211 | Get Cal View 212 | 213 | 214 | Msgs w/ Attach 215 | 216 | 217 | Get Owners 218 | 219 | 220 | Get Photo 221 | 222 | 223 | Photo Stream 224 | 225 | 226 | Sharing Link 227 | 228 | 229 | Get User Files 230 | 231 | 232 | Get User Groups 233 | 234 | 235 | Get Range 236 | 237 | 238 | Groups 239 | 240 | 241 | Move Message 242 | 243 | 244 | Applicable to personal or work accounts 245 | 246 | 247 | Please register your app before you run this sample 248 | 249 | 250 | Protect Wksht 251 | 252 | 253 | Read Users 254 | 255 | 256 | Rename File 257 | 258 | 259 | Reply Message 260 | 261 | 262 | run selected 263 | 264 | 265 | Send Message 266 | 267 | 268 | Mail w/ Attach 269 | 270 | 271 | Set Formula 272 | 273 | 274 | Sort Table 275 | 276 | 277 | Unprotect Wksht 278 | 279 | 280 | Update Event 281 | 282 | 283 | Update File 284 | 285 | 286 | Update Group 287 | 288 | 289 | Update Range 290 | 291 | 292 | Upload Large File 293 | 294 | 295 | Upload File 296 | 297 | 298 | Users 299 | 300 | 301 | Applicable to work accounts only 302 | 303 | 304 | Applicable to work accounts with admin rights 305 | 306 | 307 | ABS Func 308 | 309 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contribute to this documentation 2 | 3 | Thank you for your interest in our documentation! 4 | 5 | * [Ways to contribute](#ways-to-contribute) 6 | * [Contribute using GitHub](#contribute-using-github) 7 | * [Contribute using Git](#contribute-using-git) 8 | * [How to use Markdown to format your topic](#how-to-use-markdown-to-format-your-topic) 9 | * [FAQ](#faq) 10 | * [More resources](#more-resources) 11 | 12 | ## Ways to contribute 13 | 14 | Here are some ways you can contribute to this documentation: 15 | 16 | * To make small changes to an article, [Contribute using GitHub](#contribute-using-github). 17 | * To make large changes, or changes that involve code, [Contribute using Git](#contribute-using-git). 18 | * Report documentation bugs via GitHub Issues 19 | * Request new documentation at the [Office Developer Platform UserVoice](http://officespdev.uservoice.com) site. 20 | 21 | ## Contribute using GitHub 22 | 23 | Use GitHub to contribute to this documentation without having to clone the repo to your desktop. This is the easiest way to create a pull request in this repository. Use this method to make a minor change that doesn't involve code changes. 24 | 25 | **Note** Using this method allows you to contribute to one article at a time. 26 | 27 | ### To Contribute using GitHub 28 | 29 | 1. Find the article you want to contribute to on GitHub. 30 | 31 | If the article is in MSDN, choose the **suggest and submit changes** link in the **Contribute to this content** section and you'll be taken to the same article on GitHub. 32 | 2. Once you are on the article in GitHub, sign in to GitHub (get a free account [Join GitHub](https://github.com/join). 33 | 3. Choose the **pencil icon** (edit the file in your fork of this project) and make your changes in the **<>Edit file** window. 34 | 4. Scroll to the bottom and enter a description. 35 | 5. Choose **Propose file change**>**Create pull request**. 36 | 37 | You now have successfully submitted a pull request. Pull requests are typically reviewed within 10 business days. 38 | 39 | 40 | ## Contribute using Git 41 | 42 | Use Git to contribute substantive changes, such as: 43 | 44 | * Contributing code. 45 | * Contributing changes that affect meaning. 46 | * Contributing large changes to text. 47 | * Adding new topics. 48 | 49 | ### To Contribute using Git 50 | 51 | 1. If you don't have a GitHub account, set one up at [GitHub](https://github.com/join). 52 | 2. After you have an account, install Git on your computer. Follow the steps in [Setting up Git Tutorial](https://help.github.com/articles/set-up-git/). 53 | 3. To submit a pull request using Git, follow the steps in [Use GitHub, Git, and this repository](#use-github-git-and-this-repository). 54 | 4. You will be asked to sign the Contributor's License Agreement if you are: 55 | 56 | * A member of the Microsoft Open Technologies group. 57 | * A contributors who doesn't work for Microsoft. 58 | 59 | As a community member, you must sign the Contribution License Agreement (CLA) before you can contribute large submissions to a project. You only need to complete and submit the documentation once. Carefully review the document. You may be required to have your employer sign the document. 60 | 61 | Signing the CLA does not grant you rights to commit to the main repository, but it does mean that the Office Developer and Office Developer Content Publishing teams will be able to review and approve your contributions. You will be credited for your submissions. 62 | 63 | Pull requests are typically reviewed within 10 business days. 64 | 65 | ## Use GitHub, Git, and this repository 66 | 67 | **Note:** Most of the information in this section can be found in [GitHub Help] articles. If you're familiar with Git and GitHub, skip to the **Contribute and edit content** section for the specifics of the code/content flow of this repository. 68 | 69 | ### To set up your fork of the repository 70 | 71 | 1. Set up a GitHub account so you can contribute to this project. If you haven't done this, go to [GitHub](https://github.com/join) and do it now. 72 | 2. Install Git on your computer. Follow the steps in the [Setting up Git Tutorial] [Set Up Git]. 73 | 3. Create your own fork of this repository. To do this, at the top of the page, choose the **Fork** button. 74 | 4. Copy your fork to your computer. To do this, open Git Bash. At the command prompt enter: 75 | 76 | git clone https://github.com//.git 77 | 78 | Next, create a reference to the root repository by entering these commands: 79 | 80 | cd 81 | git remote add upstream https://github.com/microsoftgraph/.git 82 | git fetch upstream 83 | 84 | Congratulations! You've now set up your repository. You won't need to repeat these steps again. 85 | 86 | ### Contribute and edit content 87 | 88 | To make the contribution process as seamless as possible, follow these steps. 89 | 90 | #### To contribute and edit content 91 | 92 | 1. Create a new branch. 93 | 2. Add new content or edit existing content. 94 | 3. Submit a pull request to the main repository. 95 | 4. Delete the branch. 96 | 97 | **Important** Limit each branch to a single concept/article to streamline the work flow and reduce the chance of merge conflicts. Content appropriate for a new branch includes: 98 | 99 | * A new article. 100 | * Spelling and grammar edits. 101 | * Applying a single formatting change across a large set of articles (for example, applying a new copyright footer). 102 | 103 | #### To create a new branch 104 | 105 | 1. Open Git Bash. 106 | 2. At the Git Bash command prompt, type `git pull upstream master:`. This creates a new branch locally that is copied from the latest MicrosoftGraph master branch. 107 | 3. At the Git Bash command prompt, type `git push origin `. This alerts GitHub to the new branch. You should now see the new branch in your fork of the repository on GitHub. 108 | 4. At the Git Bash command prompt, type `git checkout ` to switch to your new branch. 109 | 110 | #### Add new content or edit existing content 111 | 112 | You navigate to the repository on your computer by using File Explorer. The repository files are in `C:\Users\\`. 113 | 114 | To edit files, open them in an editor of your choice and modify them. To create a new file, use the editor of your choice and save the new file in the appropriate location in your local copy of the repository. While working, save your work frequently. 115 | 116 | The files in `C:\Users\\` are a working copy of the new branch that you created in your local repository. Changing anything in this folder doesn't affect the local repository until you commit a change. To commit a change to the local repository, type the following commands in GitBash: 117 | 118 | git add . 119 | git commit -v -a -m "" 120 | 121 | The `add` command adds your changes to a staging area in preparation for committing them to the repository. The period after the `add` command specifies that you want to stage all of the files that you added or modified, checking subfolders recursively. (If you don't want to commit all of the changes, you can add specific files. You can also undo a commit. For help, type `git add -help` or `git status`.) 122 | 123 | The `commit` command applies the staged changes to the repository. The switch `-m` means you are providing the commit comment in the command line. The -v and -a switches can be omitted. The -v switch is for verbose output from the command, and -a does what you already did with the add command. 124 | 125 | You can commit multiple times while you are doing your work, or you can commit once when you're done. 126 | 127 | #### Submit a pull request to the main repository 128 | 129 | When you're finished with your work and are ready to have it merged into the main repository, follow these steps. 130 | 131 | #### To submit a pull request to the main repository 132 | 133 | 1. In the Git Bash command prompt, type `git push origin `. In your local repository, `origin` refers to your GitHub repository that you cloned the local repository from. This command pushes the current state of your new branch, including all commits made in the previous steps, to your GitHub fork. 134 | 2. On the GitHub site, navigate in your fork to the new branch. 135 | 3. Choose the **Pull Request** button at the top of the page. 136 | 4. Verify the Base branch is `microsoftgraph/@master` and the Head branch is `/@`. 137 | 5. Choose the **Update Commit Range** button. 138 | 6. Add a title to your pull request, and describe all the changes you're making. 139 | 7. Submit the pull request. 140 | 141 | One of the site administrators will process your pull request. Your pull request will surface on the microsoftgraph/ site under Issues. When the pull request is accepted, the issue will be resolved. 142 | 143 | #### Create a new branch after merge 144 | 145 | After a branch is successfully merged (that is, your pull request is accepted), don't continue working in that local branch. This can lead to merge conflicts if you submit another pull request. To do another update, create a new local branch from the successfully merged upstream branch, and then delete your initial local branch. 146 | 147 | For example, if your local branch X was successfully merged into the OfficeDev/microsoft-graph-docs master branch and you want to make additional updates to the content that was merged. Create a new local branch, X2, from the OfficeDev/microsoft-graph-docs master branch. To do this, open GitBash and execute the following commands: 148 | 149 | cd microsoft-graph-docs 150 | git pull upstream master:X2 151 | git push origin X2 152 | 153 | You now have local copies (in a new local branch) of the work that you submitted in branch X. The X2 branch also contains all the work other writers have merged, so if your work depends on others' work (for example, shared images), it is available in the new branch. You can verify that your previous work (and others' work) is in the branch by checking out the new branch... 154 | 155 | git checkout X2 156 | 157 | ...and verifying the content. (The `checkout` command updates the files in `C:\Users\\microsoft-graph-docs` to the current state of the X2 branch.) Once you check out the new branch, you can make updates to the content and commit them as usual. However, to avoid working in the merged branch (X) by mistake, it's best to delete it (see the following **Delete a branch** section). 158 | 159 | #### Delete a branch 160 | 161 | Once your changes are successfully merged into the main repository, delete the branch you used because you no longer need it. Any additional work should be done in a new branch. 162 | 163 | #### To delete a branch 164 | 165 | 1. In the Git Bash command prompt, type `git checkout master`. This ensures that you aren't in the branch to be deleted (which isn't allowed). 166 | 2. Next, at the command prompt, type `git branch -d `. This deletes the branch on your computer only if it has been successfully merged to the upstream repository. (You can override this behavior with the `–D` flag, but first be sure you want to do this.) 167 | 3. Finally, type `git push origin :` at the command prompt (a space before the colon and no space after it). This will delete the branch on your github fork. 168 | 169 | Congratulations, you have successfully contributed to the project! 170 | 171 | ## How to use Markdown to format your topic 172 | 173 | ### Article template 174 | 175 | The [markdown template](/articles/0-markdown-template-for-new-articles.md) contains the basic Markdown for a topic that includes a table of contents, sections with subheadings, links to other Office developer topics, links to other sites, bold text, italic text, numbered and bulleted lists, code snippets, and images. 176 | 177 | 178 | ### Standard Markdown 179 | 180 | All of the articles in this repository use Markdown. A complete introduction (and listing of all the syntax) can be found at [Markdown Home] []. 181 | 182 | ## FAQ 183 | 184 | ### How do I get a GitHub account? 185 | 186 | Fill out the form at [Join GitHub](https://github.com/join) to open a free GitHub account. 187 | 188 | ### Where do I get a Contributor's License Agreement? 189 | 190 | You will automatically be sent a notice that you need to sign the Contributor's License Agreement (CLA) if your pull request requires one. 191 | 192 | As a community member, **you must sign the Contribution License Agreement (CLA) before you can contribute large submissions to this project**. You only need complete and submit the documentation once. Carefully review the document. You may be required to have your employer sign the document. 193 | 194 | ### What happens with my contributions? 195 | 196 | When you submit your changes, via a pull request, our team will be notified and will review your pull request. You will receive notifications about your pull request from GitHub; you may also be notified by someone from our team if we need more information. We reserve the right to edit your submission for legal, style, clarity, or other issues. 197 | 198 | ### Can I become an approver for this repository's GitHub pull requests? 199 | 200 | Currently, we are not allowing external contributors to approve pull requests in this repository. 201 | 202 | ### How soon will I get a response about my change request or issue? 203 | 204 | We typically review pull requests and respond to issues within 10 business days. 205 | 206 | ## More resources 207 | 208 | * To learn more about Markdown, go to the Git creator's site [Daring Fireball]. 209 | * To learn more about using Git and GitHub, first check out the [GitHub Help section] [GitHub Help]. 210 | 211 | [GitHub Home]: http://github.com 212 | [GitHub Help]: http://help.github.com/ 213 | [Set Up Git]: http://help.github.com/win-set-up-git/ 214 | [Markdown Home]: http://daringfireball.net/projects/markdown/ 215 | [Daring Fireball]: http://daringfireball.net/ 216 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Users/UserStories.cs: -------------------------------------------------------------------------------- 1 | //Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. 2 | //See LICENSE in the project root for license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using Microsoft.Graph; 11 | using Windows.Storage; 12 | 13 | namespace Microsoft_Graph_Snippets_SDK 14 | { 15 | class UserStories 16 | { 17 | private static readonly string STORY_DATA_IDENTIFIER = Guid.NewGuid().ToString(); 18 | private static readonly string DEFAULT_MESSAGE_BODY = "This message was sent from the Microsoft Graph SDK UWP Snippets project"; 19 | public static ApplicationDataContainer _settings = ApplicationData.Current.RoamingSettings; 20 | 21 | public static async Task TryUploadLargeFileAsync() 22 | { 23 | var result = await UserSnippets.UploadLargeFile(); 24 | 25 | return result != null; 26 | } 27 | 28 | public static async Task TryGetMeAsync() 29 | { 30 | var currentUser = await UserSnippets.GetMeAsync(); 31 | 32 | return currentUser != null; 33 | } 34 | 35 | public static async Task TryGetUsersAsync() 36 | { 37 | var users = await UserSnippets.GetUsersAsync(); 38 | return users != null; 39 | } 40 | 41 | // This story requires an admin work account. 42 | 43 | public static async Task TryCreateUserAsync() 44 | { 45 | string createdUser = await UserSnippets.CreateUserAsync(STORY_DATA_IDENTIFIER); 46 | return createdUser != null; 47 | } 48 | 49 | public static async Task TryGetCurrentUserDriveAsync() 50 | { 51 | string driveId = await UserSnippets.GetCurrentUserDriveAsync(); 52 | return driveId != null; 53 | } 54 | 55 | public static async Task TryGetEventsAsync() 56 | { 57 | var events = await UserSnippets.GetEventsAsync(); 58 | return events != null; 59 | } 60 | 61 | public static async Task TryCreateEventAsync() 62 | { 63 | string createdEvent = await UserSnippets.CreateEventAsync(); 64 | return createdEvent != null; 65 | } 66 | 67 | public static async Task TryUpdateEventAsync() 68 | { 69 | // Create an event first, then update it. 70 | string createdEvent = await UserSnippets.CreateEventAsync(); 71 | return await UserSnippets.UpdateEventAsync(createdEvent); 72 | } 73 | 74 | public static async Task TryDeleteEventAsync() 75 | { 76 | // Create an event first, then delete it. 77 | string createdEvent = await UserSnippets.CreateEventAsync(); 78 | return await UserSnippets.DeleteEventAsync(createdEvent); 79 | } 80 | 81 | public static async Task TryGetMyCalendarViewAsync() 82 | { 83 | var calendar = await UserSnippets.GetMyCalendarViewAsync(); 84 | return calendar != null; 85 | 86 | } 87 | 88 | public static async Task TryAcceptMeetingRequestAsync() 89 | { 90 | var events = await UserSnippets.GetEventsAsync(); 91 | // Set the first event as the default meeting to accept. 92 | // This guarantees that we'll at least have a value to pass 93 | // to the snippet. 94 | // If the current user is the organizer of the meeting, the 95 | // snippet will not work, since organizers can't accept their 96 | // own invitations. 97 | string eventToAccept = events[0].Id; 98 | 99 | // Look for a meeting that didn't originate with an invitation 100 | // from the current user. If we can't find one, the snippet will 101 | // throw an exception. 102 | foreach (var myEvent in events) 103 | { 104 | if (myEvent.ResponseStatus.Response != ResponseType.Organizer) 105 | { 106 | eventToAccept = myEvent.Id; 107 | break; 108 | } 109 | } 110 | return await UserSnippets.AcceptMeetingRequestAsync(eventToAccept); 111 | } 112 | 113 | public static async Task TryGetMessages() 114 | { 115 | var messages = await UserSnippets.GetMessagesAsync(); 116 | return messages != null; 117 | } 118 | 119 | public static async Task TryGetMessagesThatHaveAttachments() 120 | { 121 | var messages = await UserSnippets.GetMessagesThatHaveAttachmentsAsync(); 122 | return messages != null; 123 | } 124 | 125 | public static async Task TrySendMailAsync() 126 | { 127 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 128 | var currentUser = await graphClient.Me.Request().GetAsync(); 129 | return await UserSnippets.SendMessageAsync( 130 | STORY_DATA_IDENTIFIER, 131 | DEFAULT_MESSAGE_BODY, 132 | currentUser.UserPrincipalName 133 | ); 134 | } 135 | 136 | public static async Task TrySendMessageWithAttachmentAsync() 137 | { 138 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 139 | var currentUser = await graphClient.Me.Request().GetAsync(); 140 | 141 | return await UserSnippets.SendMessageWithAttachmentAsync( 142 | STORY_DATA_IDENTIFIER, 143 | DEFAULT_MESSAGE_BODY, 144 | currentUser.UserPrincipalName 145 | ); 146 | } 147 | 148 | // Replies to the first message returned by the GetMessages snippet 149 | public static async Task TryReplyToMessageAsync() 150 | { 151 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 152 | var messages = await UserSnippets.GetMessagesAsync(); 153 | return await UserSnippets.ReplyToMessageAsync(messages[0].Id); 154 | } 155 | 156 | // Moves a message to the "Drafts" folder 157 | public static async Task TryMoveMessageAsync() 158 | { 159 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 160 | var currentUser = await graphClient.Me.Request().GetAsync(); 161 | 162 | var messages = await UserSnippets.GetMessagesAsync(); 163 | var message = await UserSnippets.MoveMessageAsync(messages[0].Id, "Drafts"); 164 | return message != null; 165 | } 166 | 167 | // This story does not work with a personal account 168 | public static async Task TryGetCurrentUserManagerAsync() 169 | { 170 | string managerName = await UserSnippets.GetCurrentUserManagerAsync(); 171 | return managerName != null; 172 | } 173 | 174 | // This story does not work with a personal account 175 | public static async Task TryGetDirectReportsAsync() 176 | { 177 | var users = await UserSnippets.GetDirectReportsAsync(); 178 | return users != null; 179 | } 180 | 181 | // This story does not work with a personal account 182 | public static async Task TryGetCurrentUserPhotoAsync() 183 | { 184 | string photoId = await UserSnippets.GetCurrentUserPhotoAsync(); 185 | return photoId != null; 186 | } 187 | 188 | // This story does not work with a personal account 189 | public static async Task TryGetCurrentUserPhotoStreamAsync() 190 | { 191 | Stream photoStream = await UserSnippets.GetCurrentUserPhotoStreamAsync(); 192 | return photoStream != null; 193 | } 194 | 195 | // This story requires an admin work account. 196 | public static async Task TryGetCurrentUserGroupsAsync() 197 | { 198 | var groups = await UserSnippets.GetCurrentUserGroupsAsync(); 199 | return groups != null; 200 | } 201 | 202 | public static async Task TryGetCurrentUserFilesAsync() 203 | { 204 | var files = await UserSnippets.GetCurrentUserFilesAsync(); 205 | return files != null; 206 | } 207 | 208 | public static async Task TryGetSharingLinkAsync() 209 | { 210 | string fileId = await UserSnippets.CreateFileAsync(Guid.NewGuid().ToString(), STORY_DATA_IDENTIFIER); 211 | Permission permission = await UserSnippets.GetSharingLinkAsync(fileId); 212 | return permission != null; 213 | } 214 | 215 | public static async Task TryCreateFileAsync() 216 | { 217 | var createdFileId = await UserSnippets.CreateFileAsync(Guid.NewGuid().ToString(), STORY_DATA_IDENTIFIER); 218 | return createdFileId != null; 219 | } 220 | 221 | public static async Task TryDownloadFileAsync() 222 | { 223 | var createdFileId = await UserSnippets.CreateFileAsync(Guid.NewGuid().ToString(), STORY_DATA_IDENTIFIER); 224 | var fileContent = await UserSnippets.DownloadFileAsync(createdFileId); 225 | return fileContent != null; 226 | } 227 | 228 | public static async Task TryUpdateFileAsync() 229 | { 230 | var createdFileId = await UserSnippets.CreateFileAsync(Guid.NewGuid().ToString(), STORY_DATA_IDENTIFIER); 231 | return await UserSnippets.UpdateFileAsync(createdFileId, STORY_DATA_IDENTIFIER); 232 | } 233 | 234 | public static async Task TryRenameFileAsync() 235 | { 236 | var newFileName = Guid.NewGuid().ToString(); 237 | var createdFileId = await UserSnippets.CreateFileAsync(Guid.NewGuid().ToString(), STORY_DATA_IDENTIFIER); 238 | return await UserSnippets.RenameFileAsync(createdFileId, newFileName); 239 | } 240 | 241 | public static async Task TryDeleteFileAsync() 242 | { 243 | var fileName = Guid.NewGuid().ToString(); 244 | var createdFileId = await UserSnippets.CreateFileAsync(Guid.NewGuid().ToString(), STORY_DATA_IDENTIFIER); 245 | return await UserSnippets.DeleteFileAsync(createdFileId); 246 | } 247 | 248 | // This story does not work with a consumer account. 249 | public static async Task TryCreateFolderAsync() 250 | { 251 | var createdFolderId = await UserSnippets.CreateFolderAsync(Guid.NewGuid().ToString()); 252 | return createdFolderId != null; 253 | } 254 | 255 | 256 | //Excel stories 257 | public static async Task TryUploadExcelFileAsync() 258 | { 259 | string createdFileId = await UserSnippets.UploadExcelFileAsync("excelTestResource.xlsx"); 260 | return createdFileId != null; 261 | } 262 | 263 | public static async Task TryDeleteExcelFileAsync() 264 | { 265 | string createdFileId = await UserSnippets.UploadExcelFileAsync("excelTestResource.xlsx"); 266 | bool fileDeleted = await UserSnippets.DeleteExcelFileAsync(createdFileId); 267 | return fileDeleted; 268 | } 269 | 270 | public static async Task TryCreateExcelChartFromTableAsync() 271 | { 272 | string createdFileId = await UserSnippets.UploadExcelFileAsync("excelTestResource.xlsx"); 273 | WorkbookChart excelWorkbookChart = await UserSnippets.CreateExcelChartFromTableAsync(createdFileId); 274 | return excelWorkbookChart != null; 275 | } 276 | 277 | public static async Task TryGetExcelRangeAsync() 278 | { 279 | string createdFileId = await UserSnippets.UploadExcelFileAsync("excelTestResource.xlsx"); 280 | WorkbookRange excelWorkbookRange = await UserSnippets.GetExcelRangeAsync(createdFileId); 281 | return excelWorkbookRange != null; 282 | } 283 | 284 | public static async Task TryUpdateExcelRangeAsync() 285 | { 286 | string createdFileId = await UserSnippets.UploadExcelFileAsync("excelTestResource.xlsx"); 287 | WorkbookRange excelWorkbookRange = await UserSnippets.UpdateExcelRangeAsync(createdFileId); 288 | return excelWorkbookRange != null; 289 | } 290 | 291 | public static async Task TryChangeExcelNumberFormatAsync() 292 | { 293 | string createdFileId = await UserSnippets.UploadExcelFileAsync("excelTestResource.xlsx"); 294 | WorkbookRange excelWorkbookRange = await UserSnippets.ChangeExcelNumberFormatAsync(createdFileId); 295 | return excelWorkbookRange != null; 296 | } 297 | 298 | public static async Task TryAbsExcelFunctionAsync() 299 | { 300 | string createdFileId = await UserSnippets.UploadExcelFileAsync("excelTestResource.xlsx"); 301 | WorkbookFunctionResult excelWorkbookFunctionResult = await UserSnippets.AbsExcelFunctionAsync(createdFileId); 302 | return excelWorkbookFunctionResult != null; 303 | } 304 | 305 | public static async Task TrySetExcelFormulaAsync() 306 | { 307 | string createdFileId = await UserSnippets.UploadExcelFileAsync("excelTestResource.xlsx"); 308 | WorkbookRange excelWorkbookRange = await UserSnippets.SetExcelFormulaAsync(createdFileId); 309 | return excelWorkbookRange != null; 310 | } 311 | 312 | public static async Task TryAddExcelTableToUsedRangeAsync() 313 | { 314 | string createdFileId = await UserSnippets.UploadExcelFileAsync("excelTestResource.xlsx"); 315 | WorkbookTable excelWorkbookTable = await UserSnippets.AddExcelTableToUsedRangeAsync(createdFileId); 316 | return excelWorkbookTable != null; 317 | } 318 | 319 | public static async Task TryAddExcelRowToTableAsync() 320 | { 321 | string createdFileId = await UserSnippets.UploadExcelFileAsync("excelTestResource.xlsx"); 322 | WorkbookTableRow excelWorkbookTableRow = await UserSnippets.AddExcelRowToTableAsync(createdFileId); 323 | return excelWorkbookTableRow != null; 324 | } 325 | 326 | public static async Task TrySortExcelTableOnFirstColumnValueAsync() 327 | { 328 | string createdFileId = await UserSnippets.UploadExcelFileAsync("excelTestResource.xlsx"); 329 | bool tableSorted = await UserSnippets.SortExcelTableOnFirstColumnValueAsync(createdFileId); 330 | return tableSorted; 331 | } 332 | 333 | public static async Task TryFilterExcelTableValuesAsync() 334 | { 335 | string createdFileId = await UserSnippets.UploadExcelFileAsync("excelTestResource.xlsx"); 336 | bool tableFiltered = await UserSnippets.FilterExcelTableValuesAsync(createdFileId); 337 | return tableFiltered; 338 | } 339 | 340 | public static async Task TryProtectExcelWorksheetAsync() 341 | { 342 | string createdFileId = await UserSnippets.UploadExcelFileAsync("excelTestResource.xlsx"); 343 | bool worksheetProtected = await UserSnippets.ProtectExcelWorksheetAsync(createdFileId); 344 | return worksheetProtected; 345 | } 346 | 347 | public static async Task TryUnprotectExcelWorksheetAsync() 348 | { 349 | string createdFileId = await UserSnippets.UploadExcelFileAsync("excelTestResource.xlsx"); 350 | bool worksheetUnprotected = await UserSnippets.UnprotectExcelWorksheetAsync(createdFileId); 351 | return worksheetUnprotected; 352 | } 353 | } 354 | } 355 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/MainPage.xaml.cs: -------------------------------------------------------------------------------- 1 | //Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. 2 | //See LICENSE in the project root for license information. 3 | 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Collections.ObjectModel; 8 | using System.Diagnostics; 9 | using System.IO; 10 | using System.Linq; 11 | using System.Runtime.InteropServices.WindowsRuntime; 12 | using System.Threading.Tasks; 13 | using Windows.ApplicationModel.Resources; 14 | using Windows.ApplicationModel.Resources.Core; 15 | using Windows.Foundation; 16 | using Windows.Foundation.Collections; 17 | using Windows.UI.Xaml; 18 | using Windows.UI.Xaml.Controls; 19 | using Windows.UI.Xaml.Controls.Primitives; 20 | using Windows.UI.Xaml.Data; 21 | using Windows.UI.Xaml.Input; 22 | using Windows.UI.Xaml.Media; 23 | using Windows.UI.Xaml.Navigation; 24 | 25 | // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 26 | 27 | namespace Microsoft_Graph_Snippets_SDK 28 | { 29 | /// 30 | /// An empty page that can be used on its own or navigated to within a Frame. 31 | /// 32 | public sealed partial class MainPage : Page 33 | { 34 | //Header strings for the different scope groups. 35 | public string ScopeGroupAll = ResourceLoader.GetForCurrentView().GetString("PersonalWorkAccess"); 36 | public string ScopeGroupWork = ResourceLoader.GetForCurrentView().GetString("WorkAccess"); 37 | public string ScopeGroupWorkAdmin = ResourceLoader.GetForCurrentView().GetString("WorkAdminAccess"); 38 | public string ScopeGroupExcel = ResourceLoader.GetForCurrentView().GetString("ExcelGroup"); 39 | 40 | public List StoryCollection { get; private set; } 41 | public MainPage() 42 | { 43 | this.InitializeComponent(); 44 | RunSelected.Label = ResourceLoader.GetForCurrentView().GetString("RunSelected"); 45 | ClearSelection.Label = ResourceLoader.GetForCurrentView().GetString("ClearSelected"); 46 | Disconnect.Label = ResourceLoader.GetForCurrentView().GetString("Disconnect"); 47 | CreateStoryList(); 48 | } 49 | 50 | protected override void OnNavigatedTo(NavigationEventArgs e) 51 | { 52 | // Developer code - if you haven't registered the app yet, we warn you. 53 | if (!App.Current.Resources.ContainsKey("ida:ClientID")) 54 | { 55 | Debug.WriteLine(ResourceLoader.GetForCurrentView().GetString("PleaseRegister")); 56 | 57 | } 58 | } 59 | private void CreateStoryList() 60 | { 61 | StoryCollection = new List(); 62 | 63 | // Stories applicable to both work or school and personal accounts 64 | // NOTE: All of these snippets require permissions available whether you sign into the sample 65 | // with a or work or school (commercial) or personal (consumer) account 66 | 67 | var usersGroupName = ResourceLoader.GetForCurrentView().GetString("UsersGroup"); 68 | var groupsGroupName = ResourceLoader.GetForCurrentView().GetString("GroupsGroup"); 69 | 70 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("UploadLargeFile"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryUploadLargeFileAsync }); 71 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetMe"), ScopeGroup= ScopeGroupAll, RunStoryAsync = UserStories.TryGetMeAsync }); 72 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("ReadUsers"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryGetUsersAsync }); 73 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetDrive"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryGetCurrentUserDriveAsync }); 74 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetEvents"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryGetEventsAsync }); 75 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("CreateEvent"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryCreateEventAsync }); 76 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("UpdateEvent"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryUpdateEventAsync }); 77 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("DeleteEvent"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryDeleteEventAsync }); 78 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetMyCalendarView"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryGetMyCalendarViewAsync }); 79 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("AcceptMeeting"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryAcceptMeetingRequestAsync }); 80 | 81 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetMessages"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryGetMessages }); 82 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetMyInboxMessagesThatHaveAttachments"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryGetMessagesThatHaveAttachments }); 83 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("SendMessage"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TrySendMailAsync }); 84 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("SendMessageWithAttachment"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TrySendMessageWithAttachmentAsync }); 85 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("ReplyToMessage"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryReplyToMessageAsync }); 86 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("MoveMessage"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryMoveMessageAsync }); 87 | 88 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetUserFiles"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryGetCurrentUserFilesAsync }); 89 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetSharingLink"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryGetSharingLinkAsync }); 90 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("CreateTextFile"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryCreateFileAsync }); 91 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("DownloadFile"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryDownloadFileAsync }); 92 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("UpdateFile"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryUpdateFileAsync }); 93 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("RenameFile"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryRenameFileAsync }); 94 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("DeleteFile"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryDeleteFileAsync }); 95 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("CreateFolder"), ScopeGroup = ScopeGroupAll, RunStoryAsync = UserStories.TryCreateFolderAsync }); 96 | 97 | 98 | // Stories applicable only to work or school accounts 99 | // NOTE: All of these snippets will fail for lack of permissions if you sign into the sample with a personal (consumer) account 100 | 101 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetManager"), ScopeGroup = ScopeGroupWork, RunStoryAsync = UserStories.TryGetCurrentUserManagerAsync }); 102 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetDirects"), ScopeGroup = ScopeGroupWork, RunStoryAsync = UserStories.TryGetDirectReportsAsync }); 103 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetPhoto"), ScopeGroup = ScopeGroupWork, RunStoryAsync = UserStories.TryGetCurrentUserPhotoAsync }); 104 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetPhotoStream"), ScopeGroup = ScopeGroupWork, RunStoryAsync = UserStories.TryGetCurrentUserPhotoStreamAsync }); 105 | 106 | // Stories applicable only to work or school accounts with admin access 107 | // NOTE: All of these snippets will fail for lack of permissions if you sign into the sample with a non-admin work account 108 | // or any consumer account. 109 | 110 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("CreateUser"), ScopeGroup = ScopeGroupWorkAdmin, RunStoryAsync = UserStories.TryCreateUserAsync }); 111 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetUserGroups"), ScopeGroup = ScopeGroupWorkAdmin, RunStoryAsync = UserStories.TryGetCurrentUserGroupsAsync }); 112 | StoryCollection.Add(new StoryDefinition() { GroupName = groupsGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetAllGroups"), ScopeGroup = ScopeGroupWorkAdmin, RunStoryAsync = GroupStories.TryGetGroupsAsync }); 113 | StoryCollection.Add(new StoryDefinition() { GroupName = groupsGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetAGroup"), ScopeGroup = ScopeGroupWorkAdmin, RunStoryAsync = GroupStories.TryGetGroupAsync }); 114 | StoryCollection.Add(new StoryDefinition() { GroupName = groupsGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetMembers"), ScopeGroup = ScopeGroupWorkAdmin, RunStoryAsync = GroupStories.TryGetGroupMembersAsync }); 115 | StoryCollection.Add(new StoryDefinition() { GroupName = groupsGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetOwners"), ScopeGroup = ScopeGroupWorkAdmin, RunStoryAsync = GroupStories.TryGetGroupOwnersAsync }); 116 | StoryCollection.Add(new StoryDefinition() { GroupName = groupsGroupName, Title = ResourceLoader.GetForCurrentView().GetString("CreateGroup"), ScopeGroup = ScopeGroupWorkAdmin, RunStoryAsync = GroupStories.TryCreateGroupAsync }); 117 | StoryCollection.Add(new StoryDefinition() { GroupName = groupsGroupName, Title = ResourceLoader.GetForCurrentView().GetString("UpdateGroup"), ScopeGroup = ScopeGroupWorkAdmin, RunStoryAsync = GroupStories.TryUpdateGroupAsync }); 118 | StoryCollection.Add(new StoryDefinition() { GroupName = groupsGroupName, Title = ResourceLoader.GetForCurrentView().GetString("DeleteGroup"), ScopeGroup = ScopeGroupWorkAdmin, RunStoryAsync = GroupStories.TryDeleteGroupAsync }); 119 | StoryCollection.Add(new StoryDefinition() { GroupName = groupsGroupName, Title = ResourceLoader.GetForCurrentView().GetString("AddMember"), ScopeGroup = ScopeGroupWorkAdmin, RunStoryAsync = GroupStories.TryAddUserToGroup }); 120 | 121 | // Excel snippets. These stories are applicable only to work or school accounts. 122 | // NOTE: All of these snippets will fail for lack of permissions if you sign into the sample with a personal (consumer) account 123 | 124 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("UploadXLFile"), ScopeGroup = ScopeGroupExcel, RunStoryAsync = UserStories.TryUploadExcelFileAsync }); 125 | 126 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("CreateXLChart"), ScopeGroup = ScopeGroupExcel, RunStoryAsync = UserStories.TryCreateExcelChartFromTableAsync }); 127 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("GetXLRange"), ScopeGroup = ScopeGroupExcel, RunStoryAsync = UserStories.TryGetExcelRangeAsync }); 128 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("UpdateXLRange"), ScopeGroup = ScopeGroupExcel, RunStoryAsync = UserStories.TryUpdateExcelRangeAsync }); 129 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("ChangeXLNumFormat"), ScopeGroup = ScopeGroupExcel, RunStoryAsync = UserStories.TryChangeExcelNumberFormatAsync }); 130 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("XLABSFunction"), ScopeGroup = ScopeGroupExcel, RunStoryAsync = UserStories.TryAbsExcelFunctionAsync }); 131 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("SetXLFormula"), ScopeGroup = ScopeGroupExcel, RunStoryAsync = UserStories.TrySetExcelFormulaAsync }); 132 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("AddXLTable"), ScopeGroup = ScopeGroupExcel, RunStoryAsync = UserStories.TryAddExcelTableToUsedRangeAsync }); 133 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("AddXLTableRow"), ScopeGroup = ScopeGroupExcel, RunStoryAsync = UserStories.TryAddExcelRowToTableAsync }); 134 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("SortXLTable"), ScopeGroup = ScopeGroupExcel, RunStoryAsync = UserStories.TrySortExcelTableOnFirstColumnValueAsync }); 135 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("FilterXLTable"), ScopeGroup = ScopeGroupExcel, RunStoryAsync = UserStories.TryFilterExcelTableValuesAsync }); 136 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("ProtectWorksheet"), ScopeGroup = ScopeGroupExcel, RunStoryAsync = UserStories.TryProtectExcelWorksheetAsync }); 137 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("UnprotectWorksheet"), ScopeGroup = ScopeGroupExcel, RunStoryAsync = UserStories.TryUnprotectExcelWorksheetAsync }); 138 | 139 | StoryCollection.Add(new StoryDefinition() { GroupName = usersGroupName, Title = ResourceLoader.GetForCurrentView().GetString("DeleteXLFile"), ScopeGroup = ScopeGroupExcel, RunStoryAsync = UserStories.TryDeleteExcelFileAsync }); 140 | 141 | 142 | 143 | var result = from story in StoryCollection group story by story.ScopeGroup into api orderby api.Key select api; 144 | StoriesByApi.Source = result; 145 | } 146 | 147 | 148 | private async void RunSelectedStories_Click(object sender, RoutedEventArgs e) 149 | { 150 | 151 | await runSelectedAsync(); 152 | } 153 | 154 | private async Task runSelectedAsync() 155 | { 156 | ResetStories(); 157 | Stopwatch sw = new Stopwatch(); 158 | 159 | foreach (var story in StoryGrid.SelectedItems) 160 | { 161 | StoryDefinition currentStory = story as StoryDefinition; 162 | currentStory.IsRunning = true; 163 | sw.Restart(); 164 | bool result = false; 165 | try 166 | { 167 | result = await currentStory.RunStoryAsync(); 168 | Debug.WriteLine(String.Format("{0}.{1} {2}", currentStory.GroupName, currentStory.Title, (result) ? "passed" : "failed")); 169 | } 170 | catch (Exception ex) 171 | { 172 | Debug.WriteLine("{0}.{1} failed. Exception: {2}", currentStory.GroupName, currentStory.Title, ex.Message); 173 | result = false; 174 | 175 | } 176 | currentStory.Result = result; 177 | sw.Stop(); 178 | currentStory.DurationMS = sw.ElapsedMilliseconds; 179 | currentStory.IsRunning = false; 180 | 181 | 182 | } 183 | 184 | // To shut down this app when the Stories complete, uncomment the following line. 185 | // Application.Current.Exit(); 186 | } 187 | 188 | private void ResetStories() 189 | { 190 | foreach (var story in StoryCollection) 191 | { 192 | story.Result = null; 193 | story.DurationMS = null; 194 | } 195 | } 196 | 197 | private void ClearSelection_Click(object sender, RoutedEventArgs e) 198 | { 199 | StoryGrid.SelectedItems.Clear(); 200 | } 201 | 202 | private void Disconnect_Click(object sender, RoutedEventArgs e) 203 | { 204 | AuthenticationHelper.SignOut(); 205 | StoryGrid.SelectedItems.Clear(); 206 | } 207 | 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /Microsoft-Graph-Snippets-SDK/Users/UserSnippets.cs: -------------------------------------------------------------------------------- 1 | //Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. 2 | //See LICENSE in the project root for license information. 3 | 4 | using Newtonsoft.Json.Linq; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Diagnostics; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Net.Http; 11 | using System.Text; 12 | using System.Threading.Tasks; 13 | using Microsoft.Graph; 14 | using Windows.ApplicationModel.Resources; 15 | using Windows.Storage; 16 | using Windows.Storage.Streams; 17 | using System.Runtime.InteropServices.WindowsRuntime; 18 | 19 | namespace Microsoft_Graph_Snippets_SDK 20 | { 21 | public class UserSnippets 22 | { 23 | static string ExcelFileId = null; 24 | 25 | public static async Task UploadLargeFile() 26 | { 27 | try 28 | { 29 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 30 | 31 | StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync("LargeFileUploadResource.bmp"); 32 | 33 | using (Stream fileStream = (await file.OpenReadAsync()).AsStreamForRead()) 34 | { 35 | // Create the upload session. The access token is no longer required as you have session established for the upload. 36 | // POST /v1.0/drive/root:/UploadLargeFile.bmp:/microsoft.graph.createUploadSession 37 | var uploadSession = await graphClient.Me.Drive.Root.ItemWithPath("LargeFileUploadResource.bmp").CreateUploadSession().Request().PostAsync(); 38 | 39 | var maxChunkSize = 320 * 1024; // 320 KB - Change this to your chunk size. 5MB is the default. 40 | var provider = new ChunkedUploadProvider(uploadSession, graphClient, fileStream, maxChunkSize); 41 | 42 | // Setup the chunk request necessities 43 | var chunkRequests = provider.GetUploadChunkRequests(); 44 | var readBuffer = new byte[maxChunkSize]; 45 | var trackedExceptions = new List(); 46 | DriveItem itemResult = null; 47 | 48 | //upload the chunks 49 | foreach (var request in chunkRequests) 50 | { 51 | // Do your updates here: update progress bar, etc. 52 | // ... 53 | // Send chunk request 54 | var result = await provider.GetChunkRequestResponseAsync(request, readBuffer, trackedExceptions); 55 | 56 | if (result.UploadSucceeded) 57 | { 58 | itemResult = result.ItemResponse; 59 | } 60 | } 61 | 62 | // Check that upload succeeded 63 | if (itemResult == null) 64 | { 65 | // Retry the upload 66 | // ... 67 | } 68 | 69 | return "Success"; 70 | } 71 | } 72 | 73 | catch (ServiceException e) 74 | { 75 | Debug.WriteLine("We could not upload the file: " + e.Error.Message); 76 | return null; 77 | } 78 | } 79 | 80 | // Returns information about the signed-in user 81 | public static async Task GetMeAsync() 82 | { 83 | string currentUserName = null; 84 | 85 | try 86 | { 87 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 88 | var currentUserObject = await graphClient.Me.Request().GetAsync(); 89 | currentUserName = currentUserObject.DisplayName; 90 | 91 | if (currentUserName != null) 92 | { 93 | Debug.WriteLine("Got user: " + currentUserName); 94 | } 95 | } 96 | 97 | catch (ServiceException e) 98 | { 99 | Debug.WriteLine("We could not get the current user: " + e.Error.Message); 100 | return null; 101 | } 102 | 103 | return currentUserName; 104 | } 105 | 106 | 107 | // Returns all of the users in the directory of the signed-in user's tenant. 108 | public static async Task GetUsersAsync() 109 | { 110 | IGraphServiceUsersCollectionPage users = null; 111 | 112 | try 113 | { 114 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 115 | users = await graphClient.Users.Request().GetAsync(); 116 | 117 | foreach ( var user in users) 118 | { 119 | Debug.WriteLine("User: " + user.DisplayName); 120 | } 121 | 122 | return users; 123 | 124 | } 125 | 126 | catch (ServiceException e) 127 | { 128 | Debug.WriteLine("We could not get users: " + e.Error.Message); 129 | return null; 130 | } 131 | 132 | 133 | } 134 | 135 | // Creates a new user in the signed-in user's tenant. 136 | // This snippet requires an admin work account. 137 | 138 | public static async Task CreateUserAsync(string userName) 139 | { 140 | string createdUserId = null; 141 | 142 | 143 | 144 | 145 | try 146 | { 147 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 148 | 149 | //Get tenant domain from the Organization object. We use this domain to create the 150 | //user's email address. 151 | var passwordProfile = new PasswordProfile(); 152 | passwordProfile.Password = "pass@word1"; 153 | var organization = await graphClient.Organization.Request().GetAsync(); 154 | var domain = organization.CurrentPage[0].VerifiedDomains.ElementAt(0).Name; 155 | 156 | var user = await graphClient.Users.Request().AddAsync(new User 157 | { 158 | AccountEnabled = true, 159 | DisplayName = "User " + userName, 160 | MailNickname = userName, 161 | PasswordProfile = passwordProfile, 162 | UserPrincipalName = userName + "@" + domain 163 | 164 | }); 165 | 166 | createdUserId = user.Id; 167 | Debug.WriteLine("Created user: " + createdUserId); 168 | 169 | } 170 | 171 | catch (ServiceException e) 172 | { 173 | Debug.WriteLine("We could not create a user: " + e.Error.Message); 174 | return null; 175 | } 176 | 177 | return createdUserId; 178 | 179 | } 180 | 181 | // Gets the signed-in user's drive. 182 | public static async Task GetCurrentUserDriveAsync() 183 | { 184 | string currentUserDriveId = null; 185 | 186 | try 187 | { 188 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 189 | 190 | var currentUserDrive = await graphClient.Me.Drive.Request().GetAsync(); 191 | currentUserDriveId = currentUserDrive.Id; 192 | 193 | if (currentUserDriveId != null) 194 | { 195 | Debug.WriteLine("Got user drive: " + currentUserDriveId); 196 | 197 | } 198 | 199 | } 200 | 201 | 202 | catch (ServiceException e) 203 | { 204 | Debug.WriteLine("We could not get the current user drive: " + e.Error.Message); 205 | return null; 206 | 207 | } 208 | 209 | return currentUserDriveId; 210 | 211 | } 212 | 213 | // Gets the signed-in user's calendar events. 214 | 215 | public static async Task GetEventsAsync() 216 | { 217 | IUserEventsCollectionPage events = null; 218 | 219 | try 220 | { 221 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 222 | events = await graphClient.Me.Events.Request().GetAsync(); 223 | 224 | foreach (var myEvent in events) 225 | { 226 | Debug.WriteLine("Got event: " + myEvent.Id); 227 | } 228 | 229 | } 230 | 231 | catch (ServiceException e) 232 | { 233 | Debug.WriteLine("We could not get the current user's events: " + e.Error.Message); 234 | return null; 235 | } 236 | 237 | return events; 238 | } 239 | 240 | // Creates a new event in the signed-in user's tenant. 241 | // Important note: This will create a user with a weak password. Consider deleting this user after you run the sample. 242 | public static async Task CreateEventAsync() 243 | { 244 | string createdEventId = null; 245 | 246 | //List of attendees 247 | List attendees = new List(); 248 | var attendee = new Attendee(); 249 | var emailAddress = new EmailAddress(); 250 | emailAddress.Address = "mara@fabrikam.com"; 251 | attendee.EmailAddress = emailAddress; 252 | attendee.Type = AttendeeType.Required; 253 | attendees.Add(attendee); 254 | 255 | //Event body 256 | var eventBody = new ItemBody(); 257 | eventBody.Content = "Status updates, blocking issues, and next steps"; 258 | eventBody.ContentType = BodyType.Text; 259 | 260 | //Event start and end time 261 | var eventStartTime = new DateTimeTimeZone(); 262 | eventStartTime.DateTime = new DateTime(2014, 12, 1, 9, 30, 0).ToString("o"); 263 | eventStartTime.TimeZone = "UTC"; 264 | var eventEndTime = new DateTimeTimeZone(); 265 | eventEndTime.TimeZone = "UTC"; 266 | eventEndTime.DateTime = new DateTime(2014, 12, 1, 10, 0, 0).ToString("o"); 267 | 268 | //Create an event to add to the events collection 269 | 270 | var location = new Location(); 271 | location.DisplayName = "Water cooler"; 272 | var newEvent = new Event(); 273 | newEvent.Subject = "weekly sync"; 274 | newEvent.Location = location; 275 | newEvent.Attendees = attendees; 276 | newEvent.Body = eventBody; 277 | newEvent.Start = eventStartTime; 278 | newEvent.End = eventEndTime; 279 | 280 | try 281 | { 282 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 283 | var createdEvent = await graphClient.Me.Events.Request().AddAsync(newEvent); 284 | createdEventId = createdEvent.Id; 285 | 286 | if (createdEventId != null) 287 | { 288 | Debug.WriteLine("Created event: " + createdEventId); 289 | } 290 | 291 | } 292 | 293 | catch (ServiceException e) 294 | { 295 | Debug.WriteLine("We could not create an event: " + e.Error.Message); 296 | return null; 297 | } 298 | 299 | return createdEventId; 300 | 301 | } 302 | 303 | // Updates the subject of an existing event in the signed-in user's tenant. 304 | public static async Task UpdateEventAsync(string eventId) 305 | { 306 | bool eventUpdated = false; 307 | 308 | try 309 | { 310 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 311 | var eventToUpdate = new Event(); 312 | eventToUpdate.Subject = "Sync of the week"; 313 | //eventToUpdate.IsAllDay = true; 314 | var updatedEvent = await graphClient.Me.Events[eventId].Request().UpdateAsync(eventToUpdate); 315 | 316 | if (updatedEvent != null) 317 | { 318 | Debug.WriteLine("Updated event: " + eventToUpdate.Id); 319 | eventUpdated = true; 320 | } 321 | 322 | } 323 | 324 | catch (ServiceException e) 325 | { 326 | Debug.WriteLine("We could not update the event: " + e.Error.Message); 327 | eventUpdated = false; 328 | } 329 | 330 | return eventUpdated; 331 | 332 | } 333 | 334 | // Deletes an existing event in the signed-in user's tenant. 335 | public static async Task DeleteEventAsync(string eventId) 336 | { 337 | bool eventDeleted = false; 338 | 339 | try 340 | { 341 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 342 | var eventToDelete = await graphClient.Me.Events[eventId].Request().GetAsync(); 343 | await graphClient.Me.Events[eventId].Request().DeleteAsync(); 344 | Debug.WriteLine("Deleted event: " + eventToDelete.Id); 345 | eventDeleted = true; 346 | } 347 | 348 | catch (ServiceException e) 349 | { 350 | Debug.WriteLine("We could not delete the event: " + e.Error.Message); 351 | eventDeleted = false; 352 | } 353 | 354 | return eventDeleted; 355 | 356 | } 357 | 358 | // Gets user's calendar view. 359 | 360 | public static async Task GetMyCalendarViewAsync() 361 | { 362 | ICalendarCalendarViewCollectionPage calendar = null; 363 | try 364 | { 365 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 366 | List options = new List(); 367 | options.Add(new QueryOption("startDateTime", DateTime.Now.ToString("o"))); 368 | options.Add(new QueryOption("endDateTime", DateTime.Now.AddDays(7).ToString("o"))); 369 | calendar = await graphClient.Me.Calendar.CalendarView.Request(options).GetAsync(); 370 | 371 | if (calendar?.Count > 0) 372 | { 373 | foreach (Event current in calendar) 374 | { 375 | Debug.WriteLine(current.Subject); 376 | } 377 | } 378 | 379 | 380 | } 381 | 382 | catch (ServiceException e) 383 | { 384 | Debug.WriteLine("We could not get the calendar view: " + e.Error.Message); 385 | return null; 386 | } 387 | 388 | return calendar; 389 | } 390 | 391 | // Accept a meeting request. 392 | 393 | public static async Task AcceptMeetingRequestAsync(string id) 394 | { 395 | bool meetingAccepted = false; 396 | 397 | try 398 | { 399 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 400 | var responseText = ResourceLoader.GetForCurrentView().GetString("GenericText"); 401 | 402 | await graphClient.Me.Events[id].Accept(responseText).Request().PostAsync(); 403 | Debug.WriteLine("Accepted meeting: " + id); 404 | meetingAccepted = true; 405 | } 406 | 407 | catch (ServiceException e) 408 | { 409 | Debug.WriteLine("We could not get accept the meeting: " + e.Error.Message); 410 | } 411 | 412 | return meetingAccepted; 413 | } 414 | 415 | // Returns the first page of the signed-in user's messages. 416 | public static async Task GetMessagesAsync() 417 | { 418 | IUserMessagesCollectionPage messages = null; 419 | 420 | try 421 | { 422 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 423 | messages = await graphClient.Me.Messages.Request().GetAsync(); 424 | 425 | foreach ( var message in messages) 426 | { 427 | Debug.WriteLine("Got message: " + message.Subject); 428 | } 429 | 430 | return messages; 431 | 432 | } 433 | 434 | catch (ServiceException e) 435 | { 436 | Debug.WriteLine("We could not get messages: " + e.Error.Message); 437 | return null; 438 | } 439 | 440 | 441 | } 442 | 443 | public static async Task GetMessagesThatHaveAttachmentsAsync() 444 | { 445 | IMailFolderMessagesCollectionPage messages = null; 446 | 447 | try 448 | { 449 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 450 | messages = await graphClient.Me.MailFolders.Inbox.Messages.Request().Filter("hasAttachments eq true").Expand("attachments").GetAsync(); 451 | foreach ( var message in messages) 452 | { 453 | // This snippet displays information about the first attachment in each message 454 | Attachment firstAttachment = message.Attachments[0]; 455 | Debug.WriteLine("Got message with attachment: " + message.Subject); 456 | Debug.WriteLine("Attachment name: " + firstAttachment.Name); 457 | Debug.WriteLine("Attachment content type: " + firstAttachment.ContentType); 458 | 459 | } 460 | 461 | } 462 | 463 | catch (ServiceException e) 464 | { 465 | Debug.WriteLine("We could not get messages that have attachments: " + e.Error.Message); 466 | return null; 467 | } 468 | 469 | return messages; 470 | } 471 | 472 | // Sends message to a specified address. 473 | public static async Task SendMessageAsync( 474 | string Subject, 475 | string Body, 476 | string RecipientAddress 477 | ) 478 | { 479 | bool emailSent = false; 480 | 481 | //Create recipient list 482 | List recipientList = new List(); 483 | recipientList.Add(new Recipient { EmailAddress = new EmailAddress { Address = RecipientAddress.Trim() } }); 484 | 485 | //Create message 486 | var email = new Message 487 | { 488 | Body = new ItemBody 489 | { 490 | Content = Body, 491 | ContentType = BodyType.Html, 492 | }, 493 | Subject = Subject, 494 | ToRecipients = recipientList, 495 | }; 496 | 497 | 498 | try 499 | { 500 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 501 | await graphClient.Me.SendMail(email, true).Request().PostAsync(); 502 | Debug.WriteLine("Message sent"); 503 | emailSent = true; 504 | 505 | } 506 | 507 | catch (ServiceException e) 508 | { 509 | Debug.WriteLine("We could not send the message. The request returned this status code: " + e.Error.Message); 510 | emailSent = false; 511 | } 512 | 513 | return emailSent; 514 | } 515 | 516 | // Sends message with an attachment to a specified address. 517 | public static async Task SendMessageWithAttachmentAsync( 518 | string Subject, 519 | string Body, 520 | string RecipientAddress 521 | ) 522 | { 523 | bool emailSent = false; 524 | 525 | //Create recipient list 526 | List recipientList = new List(); 527 | recipientList.Add(new Recipient { EmailAddress = new EmailAddress { Address = RecipientAddress.Trim() } }); 528 | 529 | // Create an attachment and add it to the attachments collection. 530 | StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync("excelTestResource.xlsx"); 531 | Stream fileStream = (await file.OpenReadAsync()).AsStreamForRead(); 532 | MemoryStream fileStreamMS = new MemoryStream(); 533 | // Copy stream to MemoryStream object so that it can be converted to byte array. 534 | fileStream.CopyTo(fileStreamMS); 535 | 536 | MessageAttachmentsCollectionPage attachments = new MessageAttachmentsCollectionPage(); 537 | attachments.Add(new FileAttachment 538 | { 539 | ODataType = "#microsoft.graph.fileAttachment", 540 | ContentBytes = fileStreamMS.ToArray(), 541 | ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 542 | Name = "excelTestResource.xlsx" 543 | }); 544 | 545 | //Create message 546 | var email = new Message 547 | { 548 | Body = new ItemBody 549 | { 550 | Content = Body, 551 | ContentType = BodyType.Html, 552 | }, 553 | Subject = Subject, 554 | ToRecipients = recipientList, 555 | Attachments = attachments 556 | }; 557 | 558 | 559 | try 560 | { 561 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 562 | await graphClient.Me.SendMail(email, true).Request().PostAsync(); 563 | Debug.WriteLine("Message sent"); 564 | emailSent = true; 565 | 566 | } 567 | 568 | catch (ServiceException e) 569 | { 570 | Debug.WriteLine("We could not send the message with an attachment. The request returned this status code: " + e.Error.Message); 571 | emailSent = false; 572 | } 573 | 574 | return emailSent; 575 | } 576 | 577 | // Reply to a specified message 578 | public static async Task ReplyToMessageAsync(string Id) 579 | { 580 | bool replySent = false; 581 | string responseText = ResourceLoader.GetForCurrentView().GetString("GenericText"); 582 | 583 | try 584 | { 585 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 586 | await graphClient.Me.Messages[Id].Reply(responseText).Request().PostAsync(); 587 | Debug.WriteLine("Reply sent"); 588 | replySent = true; 589 | } 590 | 591 | catch (ServiceException e) 592 | { 593 | Debug.WriteLine("We could not reply to the message. The request returned this status code: " + e.Error.Message); 594 | replySent = false; 595 | } 596 | 597 | return replySent; 598 | } 599 | 600 | // Move a specified message. This creates a new copy of the message to the specified folder. 601 | public static async Task MoveMessageAsync(string Id, string folderName) 602 | { 603 | Message message = null; 604 | 605 | try 606 | { 607 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 608 | message = await graphClient.Me.Messages[Id].Move(folderName).Request().PostAsync(); 609 | Debug.WriteLine("Message " + Id + " moved to " + folderName ); 610 | } 611 | 612 | catch (ServiceException e) 613 | { 614 | Debug.WriteLine("We could not move the message. The request returned this status code: " + e.Error.Message); 615 | } 616 | 617 | return message; 618 | 619 | } 620 | 621 | // Gets the signed-in user's manager. 622 | // This snippet doesn't work with personal accounts. 623 | public static async Task GetCurrentUserManagerAsync() 624 | { 625 | string currentUserManagerId = null; 626 | 627 | try 628 | { 629 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 630 | var currentUserManager = await graphClient.Me.Manager.Request().GetAsync(); 631 | currentUserManagerId = currentUserManager.Id; 632 | Debug.WriteLine("Got manager: " + currentUserManagerId); 633 | 634 | } 635 | 636 | catch (ServiceException e) 637 | { 638 | Debug.WriteLine("We could not get the current user's manager: " + e.Error.Message); 639 | return null; 640 | 641 | } 642 | 643 | return currentUserManagerId; 644 | 645 | } 646 | 647 | // Gets the signed-in user's direct reports. 648 | // This snippet doesn't work with consumer accounts. 649 | 650 | public static async Task GetDirectReportsAsync() 651 | { 652 | IUserDirectReportsCollectionWithReferencesPage directReports = null; 653 | 654 | try 655 | { 656 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 657 | directReports = await graphClient.Me.DirectReports.Request().GetAsync(); 658 | 659 | 660 | foreach (User direct in directReports) 661 | { 662 | Debug.WriteLine("Got direct report: " + direct.DisplayName); 663 | } 664 | 665 | return directReports; 666 | 667 | } 668 | 669 | catch (ServiceException e) 670 | { 671 | Debug.WriteLine("We could not get direct reports: " + e.Error.Message); 672 | return null; 673 | } 674 | 675 | 676 | } 677 | 678 | 679 | // Gets the signed-in user's photo. 680 | // This snippet doesn't work with consumer accounts. 681 | public static async Task GetCurrentUserPhotoAsync() 682 | { 683 | string currentUserPhotoId = null; 684 | 685 | try 686 | { 687 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 688 | var userPhoto = await graphClient.Me.Photo.Request().GetAsync(); 689 | currentUserPhotoId = userPhoto.Id; 690 | Debug.WriteLine("Got user photo: " + currentUserPhotoId); 691 | 692 | } 693 | 694 | 695 | catch (ServiceException e) 696 | { 697 | Debug.WriteLine("We could not get the current user photo: " + e.Error.Message); 698 | return null; 699 | 700 | } 701 | 702 | return currentUserPhotoId; 703 | 704 | } 705 | 706 | // Gets the stream content of the signed-in user's photo. 707 | // This snippet doesn't work with consumer accounts. 708 | public static async Task GetCurrentUserPhotoStreamAsync() 709 | { 710 | Stream currentUserPhotoStream = null; 711 | 712 | try 713 | { 714 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 715 | currentUserPhotoStream = await graphClient.Me.Photo.Content.Request().GetAsync(); 716 | Debug.WriteLine("Got user photo stream: " + currentUserPhotoStream.ToString()); 717 | 718 | } 719 | 720 | 721 | catch (ServiceException e) 722 | { 723 | Debug.WriteLine("We could not get the current user photo: " + e.Error.Message); 724 | return null; 725 | 726 | } 727 | 728 | return currentUserPhotoStream; 729 | 730 | } 731 | 732 | 733 | // Gets the groups that the signed-in user is a member of. 734 | // This snippet requires an admin work account. 735 | public static async Task GetCurrentUserGroupsAsync() 736 | { 737 | IUserMemberOfCollectionWithReferencesPage memberOfGroups = null; 738 | 739 | try 740 | { 741 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 742 | memberOfGroups = await graphClient.Me.MemberOf.Request().GetAsync(); 743 | 744 | foreach (var group in memberOfGroups) 745 | { 746 | Debug.WriteLine("Got group: " + group.Id); 747 | } 748 | 749 | return memberOfGroups; 750 | 751 | } 752 | 753 | catch (ServiceException e) 754 | { 755 | Debug.WriteLine("We could not get user groups: " + e.Error.Message); 756 | return null; 757 | } 758 | 759 | 760 | } 761 | 762 | 763 | public static async Task GetCurrentUserFilesAsync() 764 | { 765 | IDriveItemChildrenCollectionPage files = null; 766 | 767 | try 768 | { 769 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 770 | files = await graphClient.Me.Drive.Root.Children.Request().GetAsync(); 771 | foreach (DriveItem item in files) 772 | { 773 | Debug.WriteLine("Got file: " + item.Name); 774 | } 775 | 776 | return files; 777 | 778 | } 779 | 780 | catch (ServiceException e) 781 | { 782 | Debug.WriteLine("We could not get user files: " + e.Error.Message); 783 | return null; 784 | } 785 | 786 | 787 | } 788 | 789 | public static async Task GetSharingLinkAsync(string Id) 790 | { 791 | Permission permission = null; 792 | 793 | try 794 | { 795 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 796 | permission = await graphClient.Me.Drive.Items[Id].CreateLink("view").Request().PostAsync(); 797 | Debug.WriteLine("Got sharing link for file: " + permission.Link.WebUrl); 798 | } 799 | 800 | catch (ServiceException e) 801 | { 802 | Debug.WriteLine("We could not get the sharing link: " + e.Error.Message); 803 | return null; 804 | } 805 | 806 | return permission; 807 | } 808 | 809 | // Creates a text file in the user's root directory. 810 | public static async Task CreateFileAsync(string fileName, string fileContent) 811 | { 812 | string createdFileId = null; 813 | DriveItem fileToCreate = new DriveItem(); 814 | 815 | //Read fileContent string into a stream that gets passed as the file content 816 | byte[] byteArray = Encoding.ASCII.GetBytes(fileContent); 817 | MemoryStream fileContentStream = new MemoryStream(byteArray); 818 | 819 | fileToCreate.Content = fileContentStream; 820 | 821 | 822 | try 823 | { 824 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 825 | var createdFile = await graphClient.Me.Drive.Root.ItemWithPath(fileName).Content.Request().PutAsync(fileContentStream); 826 | createdFileId = createdFile.Id; 827 | 828 | Debug.WriteLine("Created file Id: " + createdFileId); 829 | 830 | 831 | } 832 | 833 | //Known bug -- file created but ServiceException "Value cannot be null" thrown 834 | //Workaround: catch the exception, make sure that it is the one that is expected, get the item and itemID 835 | catch (ServiceException se) 836 | { 837 | if (se.InnerException.Message.Contains("Value cannot be null")) 838 | { 839 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 840 | var createdFile = await graphClient.Me.Drive.Root.ItemWithPath(fileName).Request().GetAsync(); 841 | createdFileId = createdFile.Id; 842 | return createdFileId; 843 | 844 | } 845 | 846 | else 847 | { 848 | Debug.WriteLine("We could not create the file. The request returned this status code: " + se.Error.Message); 849 | return null; 850 | } 851 | 852 | } 853 | 854 | return createdFileId; 855 | } 856 | 857 | // Downloads the content of an existing file. 858 | public static async Task DownloadFileAsync(string fileId) 859 | { 860 | Stream fileContent = null; 861 | 862 | try 863 | { 864 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 865 | var downloadedFile = await graphClient.Me.Drive.Items[fileId].Content.Request().GetAsync(); 866 | fileContent = downloadedFile; 867 | Debug.WriteLine("Downloaded file content for file: " + fileId); 868 | 869 | 870 | } 871 | 872 | catch (ServiceException e) 873 | { 874 | Debug.WriteLine("We could not download the file. The request returned this status code: " + e.Error.Message); 875 | return null; 876 | } 877 | 878 | return fileContent; 879 | } 880 | 881 | // Adds content to a file in the user's root directory. 882 | public static async Task UpdateFileAsync(string fileId, string fileContent) 883 | { 884 | bool fileUpdated = false; 885 | 886 | try 887 | { 888 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 889 | 890 | //Read fileContent string into a stream that gets passed as the file content 891 | byte[] byteArray = Encoding.ASCII.GetBytes(fileContent); 892 | MemoryStream fileContentStream = new MemoryStream(byteArray); 893 | 894 | var updatedFile = await graphClient.Me.Drive.Items[fileId].Content.Request().PutAsync(fileContentStream); ; 895 | 896 | if (updatedFile != null) 897 | { 898 | Debug.WriteLine("Updated file Id: " + updatedFile.Id); 899 | fileUpdated = true; 900 | } 901 | 902 | 903 | } 904 | //Known bug -- file created but ServiceException "Value cannot be null" thrown 905 | //Workaround: catch the exception, make sure that it is the one that is expected, return true 906 | catch (ServiceException se) 907 | { 908 | if (se.InnerException.Message.Contains("Value cannot be null")) 909 | { 910 | return true; 911 | } 912 | 913 | else 914 | { 915 | Debug.WriteLine("We could not create the file. The request returned this status code: " + se.Message); 916 | return false; 917 | } 918 | 919 | } 920 | 921 | return fileUpdated; 922 | } 923 | 924 | // Deletes a file in the user's root directory. 925 | public static async Task DeleteFileAsync(string fileId) 926 | { 927 | bool fileDeleted = false; 928 | 929 | try 930 | { 931 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 932 | var fileToDelete = graphClient.Me.Drive.Items[fileId].Request().GetAsync(); 933 | await graphClient.Me.Drive.Items[fileId].Request().DeleteAsync(); 934 | Debug.WriteLine("Deleted file Id: " + fileToDelete.Id); 935 | fileDeleted = true; 936 | 937 | } 938 | 939 | catch (ServiceException e) 940 | { 941 | Debug.WriteLine("We could not delete the file. The request returned this status code: " + e.Error.Message); 942 | fileDeleted = false; 943 | } 944 | 945 | return fileDeleted; 946 | } 947 | 948 | // Renames a file in the user's root directory. 949 | public static async Task RenameFileAsync(string fileId, string newFileName) 950 | { 951 | bool fileRenamed = false; 952 | 953 | try 954 | { 955 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 956 | 957 | var fileToRename = new DriveItem(); 958 | fileToRename.Name = newFileName; 959 | var renamedFile = await graphClient.Me.Drive.Items[fileId].Request().UpdateAsync(fileToRename); 960 | 961 | if (renamedFile != null) 962 | { 963 | Debug.WriteLine("Renamed file Id: " + renamedFile.Id); 964 | fileRenamed = true; 965 | } 966 | 967 | 968 | } 969 | 970 | catch (ServiceException e) 971 | { 972 | Debug.WriteLine("We could not rename the file. The request returned this status code: " + e.Error.Message); 973 | fileRenamed = false; 974 | } 975 | 976 | return fileRenamed; 977 | } 978 | 979 | 980 | // Creates a folder in the user's root directory. 981 | // This does not work with consumer accounts. 982 | public static async Task CreateFolderAsync(string folderName) 983 | { 984 | string createFolderId = null; 985 | DriveItem folderToCreate = new DriveItem(); 986 | folderToCreate.Name = folderName; 987 | var folder = new Folder(); 988 | folderToCreate.Folder = folder; 989 | 990 | 991 | try 992 | { 993 | var graphClient = AuthenticationHelper.GetAuthenticatedClient(); 994 | var createdFolder = await graphClient.Me.Drive.Root.Children.Request().AddAsync(folderToCreate); 995 | 996 | if (createdFolder != null) 997 | { 998 | createFolderId = createdFolder.Id; 999 | Debug.WriteLine("Created folder Id: " + createFolderId); 1000 | 1001 | } 1002 | 1003 | 1004 | } 1005 | 1006 | catch (ServiceException e) 1007 | { 1008 | Debug.WriteLine("We could not create the folder. The request returned this status code: " + e.Error.Message); 1009 | return null; 1010 | } 1011 | 1012 | return createFolderId; 1013 | } 1014 | 1015 | //Excel snippets 1016 | 1017 | // Uploads a file and then streams the contents 1018 | // of an existing spreadsheet into it. You must run this at least once 1019 | // before running the other Excel snippets. Otherwise, the other snippets 1020 | // will fail, because they assume the presence of this file. 1021 | // If you quit the app and run it again 5-10 minutes after uploading 1022 | // the Excel file, the snippets will likely fail, 1023 | // because the new file won't be indexed for search yet and the app won't 1024 | // be able to retrieve the file Id 1025 | 1026 | public static async Task UploadExcelFileAsync(string fileName) 1027 | { 1028 | string createdFileId = null; 1029 | 1030 | try 1031 | { 1032 | // First test to determine whether the file exists. Create it if it doesn't. 1033 | // Don't bother to search if ExcelFileId variable is already populated. 1034 | if (ExcelFileId != null) 1035 | { 1036 | createdFileId = ExcelFileId; 1037 | } 1038 | else 1039 | { 1040 | createdFileId = await SearchForFileAsync(fileName); 1041 | } 1042 | 1043 | if (createdFileId == null) 1044 | { 1045 | 1046 | GraphServiceClient graphClient = AuthenticationHelper.GetAuthenticatedClient(); 1047 | DriveItem excelWorkbook = new DriveItem() 1048 | { 1049 | Name = fileName, 1050 | File = new Microsoft.Graph.File() 1051 | }; 1052 | 1053 | // Create the Excel file. 1054 | 1055 | DriveItem excelWorkbookDriveItem = await graphClient.Me.Drive.Root.Children.Request().AddAsync(excelWorkbook); 1056 | 1057 | createdFileId = excelWorkbookDriveItem.Id; 1058 | bool excelFileUploaded = await UploadExcelFileContentAsync(createdFileId); 1059 | 1060 | if (excelFileUploaded) 1061 | { 1062 | createdFileId = excelWorkbookDriveItem.Id; 1063 | Debug.WriteLine("Created Excel file. Name: " + fileName + " Id: " + createdFileId); 1064 | 1065 | } 1066 | 1067 | } 1068 | } 1069 | catch (ServiceException e) 1070 | { 1071 | Debug.WriteLine("We could not create the file: " + e.Error.Message); 1072 | } 1073 | 1074 | // Store the file id so that you don't have to search for it 1075 | // in subsequent snippets. 1076 | ExcelFileId = createdFileId; 1077 | return createdFileId; 1078 | } 1079 | 1080 | public static async Task SearchForFileAsync(string fileName) 1081 | { 1082 | string fileId = null; 1083 | try 1084 | { 1085 | GraphServiceClient graphClient = AuthenticationHelper.GetAuthenticatedClient(); 1086 | // Check that this item hasn't already been created. 1087 | // https://graph.microsoft.io/en-us/docs/api-reference/v1.0/api/item_search 1088 | IDriveItemSearchCollectionPage searchResults = await graphClient.Me.Drive.Root.Search(fileName).Request().GetAsync(); 1089 | foreach (var r in searchResults) 1090 | { 1091 | if (r.Name == fileName) 1092 | { 1093 | fileId = r.Id; 1094 | } 1095 | } 1096 | } 1097 | catch (Microsoft.Graph.ServiceException e) 1098 | { 1099 | Debug.WriteLine("The search for this file failed: " + e.Error.Message); 1100 | } 1101 | 1102 | return fileId; 1103 | } 1104 | 1105 | 1106 | public static async Task UploadExcelFileContentAsync(string fileId) 1107 | { 1108 | bool fileUploaded = false; 1109 | try 1110 | { 1111 | GraphServiceClient graphClient = AuthenticationHelper.GetAuthenticatedClient(); 1112 | DriveItem excelDriveItem = null; 1113 | 1114 | StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync("excelTestResource.xlsx"); 1115 | Stream fileStream = (await file.OpenReadAsync()).AsStreamForRead(); 1116 | 1117 | // Upload content to the file. 1118 | // https://graph.microsoft.io/en-us/docs/api-reference/v1.0/api/item_uploadcontent 1119 | excelDriveItem = await graphClient.Me.Drive.Items[fileId].Content.Request().PutAsync(fileStream); 1120 | 1121 | if ( excelDriveItem != null) 1122 | { 1123 | fileUploaded = true; 1124 | } 1125 | } 1126 | catch (ServiceException e) 1127 | { 1128 | Debug.WriteLine("We failed to upload the contents of the Excel file: " + e.Error.Message); 1129 | } 1130 | 1131 | return fileUploaded; 1132 | 1133 | } 1134 | 1135 | 1136 | public static async Task DeleteExcelFileAsync(string fileId) 1137 | { 1138 | 1139 | bool fileDeleted = false; 1140 | try 1141 | { 1142 | GraphServiceClient graphClient = AuthenticationHelper.GetAuthenticatedClient(); 1143 | 1144 | if (fileId != null) 1145 | { 1146 | 1147 | DriveItem w = await graphClient.Me.Drive.Items[fileId].Request().GetAsync(); 1148 | 1149 | List