├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── O365-UWP-Unified-API-Snippets.sln ├── O365-UWP-Unified-API-Snippets ├── App.xaml ├── App.xaml.cs ├── Assets │ ├── LockScreenLogo.scale-200.png │ ├── SplashScreen.scale-100.png │ ├── SplashScreen.scale-200.png │ ├── Square150x150Logo.scale-200.png │ ├── Square44x44Logo.scale-200.png │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ ├── StoreLogo.png │ └── Wide310x150Logo.scale-200.png ├── AuthenticationHelper.cs ├── Batching │ ├── BatchingSnippets.cs │ └── BatchingStories.cs ├── Contacts │ ├── OrganizationSnippets.cs │ └── OrganizationStories.cs ├── Extensions │ ├── ExtensionSnippets.cs │ └── ExtensionStories.cs ├── Groups │ ├── GroupSnippets.cs │ └── GroupStories.cs ├── MainPage.xaml ├── MainPage.xaml.cs ├── O365-UWP-Unified-API-Snippets.csproj ├── Package.appxmanifest ├── Properties │ ├── AssemblyInfo.cs │ └── Default.rd.xml ├── ResultToBrushConverter.cs ├── StoryDefinition.cs ├── Users │ ├── UserSnippets.cs │ └── UserStories.cs ├── ViewModelBase.cs ├── project.json └── project.lock.json ├── README.md └── readme-images ├── ClientTenant.png ├── appId_and_redirectURI.png └── copy_icon.png /.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "O365-UWP-Unified-API-Snippets", "O365-UWP-Unified-API-Snippets\O365-UWP-Unified-API-Snippets.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 | -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/App.xaml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 9 | 10 | 11 | 12 | 13 | urn:ietf:wg:oauth:2.0:oob 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices.WindowsRuntime; 6 | using Windows.ApplicationModel; 7 | using Windows.ApplicationModel.Activation; 8 | using Windows.Foundation; 9 | using Windows.Foundation.Collections; 10 | using Windows.UI.Xaml; 11 | using Windows.UI.Xaml.Controls; 12 | using Windows.UI.Xaml.Controls.Primitives; 13 | using Windows.UI.Xaml.Data; 14 | using Windows.UI.Xaml.Input; 15 | using Windows.UI.Xaml.Media; 16 | using Windows.UI.Xaml.Navigation; 17 | 18 | namespace O365_UWP_Unified_API_Snippets 19 | { 20 | /// 21 | /// Provides application-specific behavior to supplement the default Application class. 22 | /// 23 | sealed partial class App : Application 24 | { 25 | /// 26 | /// Initializes the singleton application object. This is the first line of authored code 27 | /// executed, and as such is the logical equivalent of main() or WinMain(). 28 | /// 29 | public App() 30 | { 31 | this.InitializeComponent(); 32 | this.Suspending += OnSuspending; 33 | } 34 | 35 | /// 36 | /// Invoked when the application is launched normally by the end user. Other entry points 37 | /// will be used such as when the application is launched to open a specific file. 38 | /// 39 | /// Details about the launch request and process. 40 | protected override void OnLaunched(LaunchActivatedEventArgs e) 41 | { 42 | 43 | #if DEBUG 44 | if (System.Diagnostics.Debugger.IsAttached) 45 | { 46 | this.DebugSettings.EnableFrameRateCounter = true; 47 | } 48 | #endif 49 | 50 | Frame rootFrame = Window.Current.Content as Frame; 51 | 52 | // Do not repeat app initialization when the Window already has content, 53 | // just ensure that the window is active 54 | if (rootFrame == null) 55 | { 56 | // Create a Frame to act as the navigation context and navigate to the first page 57 | rootFrame = new Frame(); 58 | 59 | rootFrame.NavigationFailed += OnNavigationFailed; 60 | 61 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) 62 | { 63 | //TODO: Load state from previously suspended application 64 | } 65 | 66 | // Place the frame in the current Window 67 | Window.Current.Content = rootFrame; 68 | } 69 | 70 | if (rootFrame.Content == null) 71 | { 72 | // When the navigation stack isn't restored navigate to the first page, 73 | // configuring the new page by passing required information as a navigation 74 | // parameter 75 | rootFrame.Navigate(typeof(MainPage), e.Arguments); 76 | } 77 | // Ensure the current window is active 78 | Window.Current.Activate(); 79 | } 80 | 81 | /// 82 | /// Invoked when Navigation to a certain page fails 83 | /// 84 | /// The Frame which failed navigation 85 | /// Details about the navigation failure 86 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e) 87 | { 88 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName); 89 | } 90 | 91 | /// 92 | /// Invoked when application execution is being suspended. Application state is saved 93 | /// without knowing whether the application will be terminated or resumed with the contents 94 | /// of memory still intact. 95 | /// 96 | /// The source of the suspend request. 97 | /// Details about the suspend request. 98 | private void OnSuspending(object sender, SuspendingEventArgs e) 99 | { 100 | var deferral = e.SuspendingOperation.GetDeferral(); 101 | //TODO: Save application state and stop any background activity 102 | deferral.Complete(); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Assets/LockScreenLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-rest-sample/36c03fb66affd60eb818bdd8ec4bafa380660a15/O365-UWP-Unified-API-Snippets/Assets/LockScreenLogo.scale-200.png -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Assets/SplashScreen.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-rest-sample/36c03fb66affd60eb818bdd8ec4bafa380660a15/O365-UWP-Unified-API-Snippets/Assets/SplashScreen.scale-100.png -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-rest-sample/36c03fb66affd60eb818bdd8ec4bafa380660a15/O365-UWP-Unified-API-Snippets/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-rest-sample/36c03fb66affd60eb818bdd8ec4bafa380660a15/O365-UWP-Unified-API-Snippets/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-rest-sample/36c03fb66affd60eb818bdd8ec4bafa380660a15/O365-UWP-Unified-API-Snippets/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Assets/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-rest-sample/36c03fb66affd60eb818bdd8ec4bafa380660a15/O365-UWP-Unified-API-Snippets/Assets/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Assets/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-rest-sample/36c03fb66affd60eb818bdd8ec4bafa380660a15/O365-UWP-Unified-API-Snippets/Assets/StoreLogo.png -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-rest-sample/36c03fb66affd60eb818bdd8ec4bafa380660a15/O365-UWP-Unified-API-Snippets/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/AuthenticationHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 2 | 3 | 4 | using System; 5 | using System.Diagnostics; 6 | using System.Net.Http; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | using Windows.Security.Authentication.Web; 10 | using Windows.Security.Authentication.Web.Core; 11 | using Windows.Security.Credentials; 12 | using Windows.Storage; 13 | using Microsoft.Identity.Client; 14 | 15 | namespace O365_UWP_Unified_API_Snippets 16 | { 17 | public class AuthenticationHelper 18 | { 19 | // The Client ID is used by the application to uniquely identify itself to the v2.0 authentication endpoint. 20 | static string clientId = App.Current.Resources["ida:ClientID"].ToString(); 21 | 22 | public static PublicClientApplication IdentityClientApp = new PublicClientApplication(clientId) 23 | { 24 | RedirectUri = App.Current.Resources["ida:ReturnUrl"].ToString() 25 | }; 26 | 27 | public static string TokenForUser = null; 28 | public static DateTimeOffset Expiration; 29 | public static ApplicationDataContainer _settings = ApplicationData.Current.RoamingSettings; 30 | 31 | /// 32 | /// Get Token for User. 33 | /// 34 | /// Token for user. 35 | public static async Task GetTokenForUserAsync() 36 | { 37 | AuthenticationResult authResult; 38 | var scopes = new string[] 39 | 40 | { 41 | "https://graph.microsoft.com/User.Read", 42 | "https://graph.microsoft.com/User.ReadWrite", 43 | "https://graph.microsoft.com/User.ReadBasic.All", 44 | "https://graph.microsoft.com/Mail.Send", 45 | "https://graph.microsoft.com/Calendars.ReadWrite", 46 | "https://graph.microsoft.com/Mail.ReadWrite", 47 | "https://graph.microsoft.com/Files.ReadWrite", 48 | 49 | // Admin-only scopes. Uncomment these if you're running the sample with an admin work account. 50 | // You won't be able to sign in with a non-admin work account if you request these scopes. 51 | // These scopes will be ignored if you leave them uncommented and run the sample with a consumer account. 52 | // See the MainPage.xaml.cs file for all of the operations that won't work if you're not running the 53 | // sample with an admin work account. 54 | //"https://graph.microsoft.com/User.ReadWrite.All", 55 | //"https://graph.microsoft.com/Group.ReadWrite.All", 56 | //"https://graph.microsoft.com/Directory.AccessAsUser.All" 57 | }; 58 | 59 | try 60 | { 61 | authResult = await IdentityClientApp.AcquireTokenSilentAsync(scopes, IdentityClientApp.Users.FirstOrDefault()); 62 | TokenForUser = authResult.AccessToken; 63 | // save user ID in local storage 64 | _settings.Values["userEmail"] = authResult.User.DisplayableId; 65 | _settings.Values["userName"] = authResult.User.Name; 66 | } 67 | catch (MsalUiRequiredException) 68 | { 69 | authResult = await IdentityClientApp.AcquireTokenAsync(scopes); 70 | 71 | TokenForUser = authResult.AccessToken; 72 | Expiration = authResult.ExpiresOn; 73 | 74 | // save user ID in local storage 75 | _settings.Values["userEmail"] = authResult.User.DisplayableId; 76 | _settings.Values["userName"] = authResult.User.Name; 77 | } 78 | catch (Exception exc) 79 | { 80 | Debug.WriteLine(exc.StackTrace); 81 | } 82 | 83 | return TokenForUser; 84 | } 85 | 86 | /// 87 | /// Signs the user out of the service. 88 | /// 89 | public static void SignOut() 90 | { 91 | foreach (var user in IdentityClientApp.Users) 92 | { 93 | IdentityClientApp.Remove(user); 94 | } 95 | 96 | TokenForUser = null; 97 | 98 | //Clear stored values from last authentication. 99 | _settings.Values["userEmail"] = null; 100 | _settings.Values["userName"] = null; 101 | 102 | } 103 | 104 | } 105 | } 106 | 107 | //********************************************************* 108 | // 109 | //O365-UWP-Microsoft-Graph-Snippets, https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets 110 | // 111 | //Copyright (c) Microsoft Corporation 112 | //All rights reserved. 113 | // 114 | // MIT License: 115 | // Permission is hereby granted, free of charge, to any person obtaining 116 | // a copy of this software and associated documentation files (the 117 | // "Software"), to deal in the Software without restriction, including 118 | // without limitation the rights to use, copy, modify, merge, publish, 119 | // distribute, sublicense, and/or sell copies of the Software, and to 120 | // permit persons to whom the Software is furnished to do so, subject to 121 | // the following conditions: 122 | 123 | // The above copyright notice and this permission notice shall be 124 | // included in all copies or substantial portions of the Software. 125 | 126 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 127 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 128 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 129 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 130 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 131 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 132 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 133 | // 134 | //********************************************************* -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Batching/BatchingSnippets.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 2 | 3 | using Newtonsoft.Json; 4 | using Newtonsoft.Json.Linq; 5 | using System.Diagnostics; 6 | using System.Net; 7 | using System.Net.Http; 8 | using System.Net.Http.Headers; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace O365_UWP_Unified_API_Snippets 13 | { 14 | class BatchingSnippets 15 | { 16 | const string Endpoint = "https://graph.microsoft.com/beta/$batch"; 17 | 18 | internal static async Task ParallelBatchCallAsync() 19 | { 20 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 21 | 22 | using (var client = new HttpClient()) 23 | { 24 | using (var request = new HttpRequestMessage(HttpMethod.Post, Endpoint)) 25 | { 26 | request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 27 | JArray batchRequests = new JArray 28 | { 29 | new JObject 30 | { 31 | { "url", "/me" }, 32 | { "method", "GET" }, 33 | { "id", "1" } 34 | }, 35 | new JObject 36 | { 37 | { "url", "/me/manager" }, 38 | { "method", "GET" }, 39 | { "id", "2" } 40 | }, 41 | new JObject 42 | { 43 | { "url", "me/messages?$top=5" }, 44 | { "method", "GET" }, 45 | { "id", "3" } 46 | }, 47 | new JObject 48 | { 49 | { "url", "/me/photo/$value" }, 50 | { "method", "GET" }, 51 | { "id", "4" } 52 | }, 53 | }; 54 | 55 | JObject batchPayload = new JObject(new JProperty("requests", batchRequests)); 56 | 57 | request.Content = new StringContent(JsonConvert.SerializeObject(batchPayload), Encoding.UTF8, "application/json"); 58 | request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); 59 | 60 | // This header has been added to identify our sample in the Microsoft Graph service. If extracting this code for your project please remove. 61 | request.Headers.Add("SampleID", "aspnet-connect-rest-sample"); 62 | 63 | using (HttpResponseMessage response = await client.SendAsync(request)) 64 | { 65 | if (response.StatusCode == HttpStatusCode.OK) 66 | { 67 | var json = JObject.Parse(await response.Content.ReadAsStringAsync()); 68 | return json.ToString(); 69 | } 70 | else 71 | { 72 | Debug.WriteLine("We could not run parallel batch request. The request returned this status code: " + response.StatusCode); 73 | return null; 74 | } 75 | } 76 | } 77 | } 78 | } 79 | 80 | internal static async Task SequentialBatchCallAsync() 81 | { 82 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 83 | using (var client = new HttpClient()) 84 | { 85 | using (var request = new HttpRequestMessage(HttpMethod.Post, Endpoint)) 86 | { 87 | request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 88 | JArray batchRequests = new JArray 89 | { 90 | new JObject 91 | { 92 | { "url", "/me/events?$top=2" }, 93 | { "method", "GET" }, 94 | { "id", "1" } 95 | }, 96 | new JObject 97 | { 98 | { "url", "/me/drive/root/children" }, 99 | { "method", "POST" }, 100 | { "id", "2" }, 101 | { "body", new JObject 102 | { 103 | { "name", "BatchingTestFolder"}, 104 | { "folder", new JObject()} 105 | } 106 | }, 107 | { "headers", new JObject { { "Content-Type", "application/json" } } }, 108 | { "dependsOn", new JArray("1")} 109 | }, 110 | new JObject 111 | { 112 | { "url", "/me/drive/root/children/BatchingTestFolder" }, 113 | { "method", "GET" }, 114 | { "id", "3" }, 115 | { "dependsOn", new JArray("2")} 116 | }, 117 | new JObject 118 | { 119 | { "url", "/me/drive/root/children/BatchingTestFolder" }, 120 | { "method", "DELETE" }, 121 | { "id", "4" }, 122 | { "dependsOn", new JArray("3")} 123 | } 124 | }; 125 | 126 | JObject batchPayload = new JObject(new JProperty("requests", batchRequests)); 127 | 128 | request.Content = new StringContent(JsonConvert.SerializeObject(batchPayload), Encoding.UTF8, "application/json"); 129 | request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); 130 | 131 | // This header has been added to identify our sample in the Microsoft Graph service. If extracting this code for your project please remove. 132 | request.Headers.Add("SampleID", "aspnet-connect-rest-sample"); 133 | 134 | using (HttpResponseMessage response = await client.SendAsync(request)) 135 | { 136 | if (response.StatusCode == HttpStatusCode.OK) 137 | { 138 | var json = JObject.Parse(await response.Content.ReadAsStringAsync()); 139 | return json.ToString(); 140 | } 141 | else 142 | { 143 | Debug.WriteLine("We could not run sequential batch request. The request returned this status code: " + response.StatusCode); 144 | return null; 145 | } 146 | } 147 | } 148 | } 149 | } 150 | } 151 | } 152 | //********************************************************* 153 | // 154 | //O365-UWP-Microsoft-Graph-Snippets, https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets 155 | // 156 | //Copyright (c) Microsoft Corporation 157 | //All rights reserved. 158 | // 159 | // MIT License: 160 | // Permission is hereby granted, free of charge, to any person obtaining 161 | // a copy of this software and associated documentation files (the 162 | // "Software"), to deal in the Software without restriction, including 163 | // without limitation the rights to use, copy, modify, merge, publish, 164 | // distribute, sublicense, and/or sell copies of the Software, and to 165 | // permit persons to whom the Software is furnished to do so, subject to 166 | // the following conditions: 167 | 168 | // The above copyright notice and this permission notice shall be 169 | // included in all copies or substantial portions of the Software. 170 | 171 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 172 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 173 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 174 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 175 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 176 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 177 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 178 | // 179 | //********************************************************* -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Batching/BatchingStories.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 2 | 3 | using System.Threading.Tasks; 4 | 5 | namespace O365_UWP_Unified_API_Snippets 6 | { 7 | class BatchingStories 8 | { 9 | 10 | public static async Task TryRunParallelBatch() 11 | { 12 | var batchResponse = await BatchingSnippets.ParallelBatchCallAsync(); 13 | return batchResponse != null; 14 | } 15 | 16 | public static async Task TryRunSequentialBatch() 17 | { 18 | var batchResponse = await BatchingSnippets.SequentialBatchCallAsync(); 19 | return batchResponse != null; 20 | } 21 | } 22 | } 23 | 24 | //********************************************************* 25 | // 26 | //O365-UWP-Microsoft-Graph-Snippets, https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets 27 | // 28 | //Copyright (c) Microsoft Corporation 29 | //All rights reserved. 30 | // 31 | // MIT License: 32 | // Permission is hereby granted, free of charge, to any person obtaining 33 | // a copy of this software and associated documentation files (the 34 | // "Software"), to deal in the Software without restriction, including 35 | // without limitation the rights to use, copy, modify, merge, publish, 36 | // distribute, sublicense, and/or sell copies of the Software, and to 37 | // permit persons to whom the Software is furnished to do so, subject to 38 | // the following conditions: 39 | 40 | // The above copyright notice and this permission notice shall be 41 | // included in all copies or substantial portions of the Software. 42 | 43 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 44 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 45 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 46 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 47 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 48 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 49 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 50 | // 51 | //********************************************************* -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Contacts/OrganizationSnippets.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 2 | 3 | using Newtonsoft.Json.Linq; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Diagnostics; 7 | using System.Linq; 8 | using System.Net.Http; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace O365_UWP_Unified_API_Snippets 13 | { 14 | class OrganizationSnippets 15 | { 16 | const string serviceEndpoint = "https://graph.microsoft.com/v1.0/"; 17 | 18 | // Returns all of the contacts in your tenant's directory. 19 | // Returns all of the drives in your tenant's directory. 20 | public static async Task> GetDrivesAsync() 21 | { 22 | var drives = new List(); 23 | JObject jResult = null; 24 | 25 | try 26 | { 27 | HttpClient client = new HttpClient(); 28 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 29 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 30 | 31 | // Endpoint for all contacts in your organization 32 | Uri contactsEndpoint = new Uri(serviceEndpoint + "myOrganization/drives"); 33 | 34 | HttpResponseMessage response = await client.GetAsync(contactsEndpoint); 35 | 36 | if (response.IsSuccessStatusCode) 37 | { 38 | string responseContent = await response.Content.ReadAsStringAsync(); 39 | jResult = JObject.Parse(responseContent); 40 | 41 | foreach (JObject contact in jResult["value"]) 42 | { 43 | string driveId = (string)contact["Id"]; 44 | drives.Add(driveId); 45 | Debug.WriteLine("Got contact: " + driveId); 46 | } 47 | } 48 | 49 | else 50 | { 51 | Debug.WriteLine("We could not get drives. The request returned this status code: " + response.StatusCode); 52 | return null; 53 | } 54 | 55 | return drives; 56 | 57 | } 58 | 59 | catch (Exception e) 60 | { 61 | Debug.WriteLine("We could not get drives: " + e.Message); 62 | return null; 63 | } 64 | } 65 | 66 | } 67 | } 68 | //********************************************************* 69 | // 70 | //O365-UWP-Microsoft-Graph-Snippets, https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets 71 | // 72 | //Copyright (c) Microsoft Corporation 73 | //All rights reserved. 74 | // 75 | // MIT License: 76 | // Permission is hereby granted, free of charge, to any person obtaining 77 | // a copy of this software and associated documentation files (the 78 | // "Software"), to deal in the Software without restriction, including 79 | // without limitation the rights to use, copy, modify, merge, publish, 80 | // distribute, sublicense, and/or sell copies of the Software, and to 81 | // permit persons to whom the Software is furnished to do so, subject to 82 | // the following conditions: 83 | 84 | // The above copyright notice and this permission notice shall be 85 | // included in all copies or substantial portions of the Software. 86 | 87 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 88 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 89 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 90 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 91 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 92 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 93 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 94 | // 95 | //********************************************************* -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Contacts/OrganizationStories.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using Windows.Storage; 9 | 10 | namespace O365_UWP_Unified_API_Snippets 11 | { 12 | class OrganizationStories 13 | { 14 | 15 | public static async Task TryGetDrivesAsync() 16 | { 17 | var drives = await OrganizationSnippets.GetDrivesAsync(); 18 | return drives != null; 19 | } 20 | 21 | } 22 | } 23 | 24 | //********************************************************* 25 | // 26 | //O365-UWP-Microsoft-Graph-Snippets, https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets 27 | // 28 | //Copyright (c) Microsoft Corporation 29 | //All rights reserved. 30 | // 31 | // MIT License: 32 | // Permission is hereby granted, free of charge, to any person obtaining 33 | // a copy of this software and associated documentation files (the 34 | // "Software"), to deal in the Software without restriction, including 35 | // without limitation the rights to use, copy, modify, merge, publish, 36 | // distribute, sublicense, and/or sell copies of the Software, and to 37 | // permit persons to whom the Software is furnished to do so, subject to 38 | // the following conditions: 39 | 40 | // The above copyright notice and this permission notice shall be 41 | // included in all copies or substantial portions of the Software. 42 | 43 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 44 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 45 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 46 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 47 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 48 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 49 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 50 | // 51 | //********************************************************* -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Extensions/ExtensionSnippets.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 2 | 3 | using Newtonsoft.Json; 4 | using Newtonsoft.Json.Linq; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Diagnostics; 8 | using System.Linq; 9 | using System.Net; 10 | using System.Net.Http; 11 | using System.Net.Http.Headers; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | 15 | namespace O365_UWP_Unified_API_Snippets 16 | { 17 | class ExtensionSnippets 18 | { 19 | const string serviceEndpoint = "https://graph.microsoft.com/beta"; 20 | 21 | // These snippets require you to supply the name of a verified domain on your tenant. 22 | // You won't be able to run these snippets without a verified domain. 23 | const string domainName = "your verified domain"; 24 | 25 | internal static async Task GetOpenExtensionsAsync() 26 | { 27 | string endpoint = serviceEndpoint + "/me/extensions/sampleSettings"; 28 | 29 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 30 | 31 | using (var client = new HttpClient()) 32 | { 33 | using (var request = new HttpRequestMessage(HttpMethod.Get, endpoint)) 34 | { 35 | request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 36 | request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); 37 | 38 | // This header has been added to identify our sample in the Microsoft Graph service. If extracting this code for your project please remove. 39 | request.Headers.Add("SampleID", "aspnet-connect-rest-sample"); 40 | using (HttpResponseMessage response = await client.SendAsync(request)) 41 | { 42 | if (response.StatusCode == HttpStatusCode.OK) 43 | { 44 | var json = JObject.Parse(await response.Content.ReadAsStringAsync()); 45 | return json.ToString(); 46 | } 47 | else 48 | { 49 | Debug.WriteLine("We could not get extensions. The request returned this status code: " + response.StatusCode); 50 | return null; 51 | } 52 | } 53 | } 54 | } 55 | } 56 | 57 | internal static async Task SetOpenExtensionsAsync() 58 | { 59 | string endpoint = null; 60 | string openExtensionPropertyName = "prop1"; 61 | string openExtensionPropertyValue = "value1"; 62 | string settingName = "sampleSettings"; 63 | JObject setting = new JObject 64 | { 65 | { "id", settingName }, 66 | {openExtensionPropertyName, openExtensionPropertyValue} 67 | }; 68 | 69 | endpoint = serviceEndpoint + "/me/extensions/sampleSettings"; 70 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 71 | 72 | using (var client = new HttpClient()) 73 | { 74 | using (var request = new HttpRequestMessage(new HttpMethod("PATCH"), endpoint)) 75 | { 76 | request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); 77 | 78 | // This header has been added to identify our sample in the Microsoft Graph service. If extracting this code for your project please remove. 79 | request.Headers.Add("SampleID", "aspnet-connect-rest-sample"); 80 | request.Content = new StringContent(JsonConvert.SerializeObject(setting), Encoding.UTF8, "application/json"); 81 | using (HttpResponseMessage response = await client.SendAsync(request)) 82 | { 83 | if (response.IsSuccessStatusCode) 84 | { 85 | return "Success!"; 86 | } 87 | else 88 | { 89 | endpoint = serviceEndpoint + "/me/extensions"; 90 | using (var request2 = new HttpRequestMessage(new HttpMethod("POST"), endpoint)) 91 | { 92 | request2.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); 93 | 94 | request2.Headers.Add("SampleID", "aspnet-connect-rest-sample"); 95 | request2.Content = new StringContent(JsonConvert.SerializeObject(setting), Encoding.UTF8, "application/json"); 96 | 97 | using (HttpResponseMessage response2 = await client.SendAsync(request2)) 98 | { 99 | if (response2.IsSuccessStatusCode) 100 | { 101 | return "Success!"; 102 | } 103 | 104 | return null; 105 | } 106 | } 107 | } 108 | } 109 | } 110 | } 111 | } 112 | 113 | internal static async Task DeleteSchemaExtensionsAsync() 114 | { 115 | string extName = domainName + "_hrprofile"; 116 | string endpoint = serviceEndpoint + "/schemaExtensions/" + extName; 117 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 118 | 119 | using (var client = new HttpClient()) 120 | { 121 | using (var request = new HttpRequestMessage(HttpMethod.Delete, endpoint)) 122 | { 123 | request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); 124 | 125 | // This header has been added to identify our sample in the Microsoft Graph service. If extracting this code for your project please remove. 126 | request.Headers.Add("SampleID", "aspnet-connect-rest-sample"); 127 | using (HttpResponseMessage response = await client.SendAsync(request)) 128 | { 129 | if (response.IsSuccessStatusCode) 130 | { 131 | return "Success!"; 132 | } 133 | else 134 | { 135 | return null; 136 | } 137 | } 138 | } 139 | } 140 | } 141 | 142 | internal static async Task GetSchemaExtensionValueAsync() 143 | { 144 | string extName = domainName + "_hrprofile"; 145 | string endpoint = serviceEndpoint + "/me?$select=" + extName; 146 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 147 | 148 | using (var client = new HttpClient()) 149 | { 150 | using (var request = new HttpRequestMessage(HttpMethod.Get, endpoint)) 151 | { 152 | request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 153 | request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); 154 | 155 | // This header has been added to identify our sample in the Microsoft Graph service. If extracting this code for your project please remove. 156 | request.Headers.Add("SampleID", "aspnet-connect-rest-sample"); 157 | using (HttpResponseMessage response = await client.SendAsync(request)) 158 | { 159 | if (response.StatusCode == HttpStatusCode.OK) 160 | { 161 | var json = JObject.Parse(await response.Content.ReadAsStringAsync()); 162 | return json.ToString(); 163 | } 164 | 165 | return null; 166 | } 167 | } 168 | } 169 | } 170 | 171 | internal static async Task SetExtensionValueAsync() 172 | { 173 | string endpoint = serviceEndpoint + "/me"; 174 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 175 | string extName = domainName + "_hrprofile"; 176 | string propName = "p1"; 177 | string propValue = "value"; 178 | 179 | JObject extensionValue = new JObject 180 | { 181 | { 182 | extName, new JObject { 183 | {propName, propValue } 184 | } 185 | }, 186 | }; 187 | 188 | using (var client = new HttpClient()) 189 | { 190 | using (var request = new HttpRequestMessage(new HttpMethod("PATCH"), endpoint)) 191 | { 192 | request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); 193 | 194 | // This header has been added to identify our sample in the Microsoft Graph service. If extracting this code for your project please remove. 195 | request.Headers.Add("SampleID", "aspnet-connect-rest-sample"); 196 | request.Content = new StringContent(JsonConvert.SerializeObject(extensionValue), Encoding.UTF8, "application/json"); 197 | using (HttpResponseMessage response = await client.SendAsync(request)) 198 | { 199 | if (response.IsSuccessStatusCode) 200 | { 201 | return "Success"; 202 | } 203 | else 204 | { 205 | return null; 206 | } 207 | } 208 | } 209 | } 210 | } 211 | 212 | internal static async Task GetSchemaExtensionsAsync() 213 | { 214 | string extName = domainName + "_hrprofile"; 215 | string endpoint = serviceEndpoint + "/schemaExtensions/" + extName; 216 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 217 | 218 | using (var client = new HttpClient()) 219 | { 220 | using (var request = new HttpRequestMessage(HttpMethod.Get, endpoint)) 221 | { 222 | request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); 223 | 224 | // This header has been added to identify our sample in the Microsoft Graph service. If extracting this code for your project please remove. 225 | request.Headers.Add("SampleID", "aspnet-connect-rest-sample"); 226 | using (HttpResponseMessage response = await client.SendAsync(request)) 227 | { 228 | if (response.IsSuccessStatusCode) 229 | { 230 | return "Success!"; 231 | } 232 | else 233 | { 234 | return null; 235 | } 236 | } 237 | } 238 | } 239 | } 240 | 241 | internal static async Task RegisterSchemaExtensionsAsync() 242 | { 243 | string endpoint = serviceEndpoint + "/schemaExtensions"; 244 | string extName = domainName + "_hrprofile"; 245 | string propName = "p1"; 246 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 247 | 248 | JObject schemaExt = new JObject 249 | { 250 | { "status", "InDevelopment"}, 251 | { "id", extName }, 252 | { "targetTypes",new JArray(new string[] { "User"} )}, 253 | { "description","Extension description"}, 254 | { "properties", new JArray(new JObject[] 255 | { 256 | new JObject { { "name", propName }, { "type", "String" } } 257 | }) 258 | } 259 | }; 260 | 261 | using (var client = new HttpClient()) 262 | { 263 | using (var request = new HttpRequestMessage(HttpMethod.Post, endpoint)) 264 | { 265 | request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); 266 | 267 | // This header has been added to identify our sample in the Microsoft Graph service. If extracting this code for your project please remove. 268 | request.Headers.Add("SampleID", "aspnet-connect-rest-sample"); 269 | request.Content = new StringContent(JsonConvert.SerializeObject(schemaExt), Encoding.UTF8, "application/json"); 270 | using (HttpResponseMessage response = await client.SendAsync(request)) 271 | { 272 | if (response.IsSuccessStatusCode) 273 | { 274 | return "Success!"; 275 | } 276 | else 277 | { 278 | var json = JObject.Parse(await response.Content.ReadAsStringAsync()); 279 | return null; 280 | } 281 | } 282 | } 283 | } 284 | } 285 | } 286 | } 287 | //********************************************************* 288 | // 289 | //O365-UWP-Microsoft-Graph-Snippets, https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets 290 | // 291 | //Copyright (c) Microsoft Corporation 292 | //All rights reserved. 293 | // 294 | // MIT License: 295 | // Permission is hereby granted, free of charge, to any person obtaining 296 | // a copy of this software and associated documentation files (the 297 | // "Software"), to deal in the Software without restriction, including 298 | // without limitation the rights to use, copy, modify, merge, publish, 299 | // distribute, sublicense, and/or sell copies of the Software, and to 300 | // permit persons to whom the Software is furnished to do so, subject to 301 | // the following conditions: 302 | 303 | // The above copyright notice and this permission notice shall be 304 | // included in all copies or substantial portions of the Software. 305 | 306 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 307 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 308 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 309 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 310 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 311 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 312 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 313 | // 314 | //********************************************************* -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Extensions/ExtensionStories.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using Windows.Storage; 9 | 10 | namespace O365_UWP_Unified_API_Snippets 11 | { 12 | class ExtensionStories 13 | { 14 | 15 | public static async Task TryGetOpenExtension() 16 | { 17 | var extensions = await ExtensionSnippets.GetOpenExtensionsAsync(); 18 | return extensions != null; 19 | } 20 | 21 | public static async Task TrySetOpenExtension() 22 | { 23 | var extensions = await ExtensionSnippets.SetOpenExtensionsAsync(); 24 | return extensions != null; 25 | } 26 | 27 | public static async Task TryRegisterSchemaExtension() 28 | { 29 | var extensions = await ExtensionSnippets.RegisterSchemaExtensionsAsync(); 30 | return extensions != null; 31 | } 32 | 33 | public static async Task TryGetSchemaExtension() 34 | { 35 | var extensions = await ExtensionSnippets.GetSchemaExtensionsAsync(); 36 | return extensions != null; 37 | } 38 | 39 | public static async Task TrySetSchemaExtensionValue() 40 | { 41 | var extensions = await ExtensionSnippets.SetExtensionValueAsync(); 42 | return extensions != null; 43 | } 44 | 45 | public static async Task TryGetSchemaExtensionValue() 46 | { 47 | var extensions = await ExtensionSnippets.GetSchemaExtensionValueAsync(); 48 | return extensions != null; 49 | } 50 | 51 | public static async Task TryDeleteSchemaExtension() 52 | { 53 | var extensions = await ExtensionSnippets.DeleteSchemaExtensionsAsync(); 54 | return extensions != null; 55 | } 56 | } 57 | } 58 | 59 | //********************************************************* 60 | // 61 | //O365-UWP-Microsoft-Graph-Snippets, https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets 62 | // 63 | //Copyright (c) Microsoft Corporation 64 | //All rights reserved. 65 | // 66 | // MIT License: 67 | // Permission is hereby granted, free of charge, to any person obtaining 68 | // a copy of this software and associated documentation files (the 69 | // "Software"), to deal in the Software without restriction, including 70 | // without limitation the rights to use, copy, modify, merge, publish, 71 | // distribute, sublicense, and/or sell copies of the Software, and to 72 | // permit persons to whom the Software is furnished to do so, subject to 73 | // the following conditions: 74 | 75 | // The above copyright notice and this permission notice shall be 76 | // included in all copies or substantial portions of the Software. 77 | 78 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 79 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 80 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 81 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 82 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 83 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 84 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 85 | // 86 | //********************************************************* -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Groups/GroupSnippets.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 2 | 3 | using Newtonsoft.Json.Linq; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Diagnostics; 7 | using System.Linq; 8 | using System.Net.Http; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace O365_UWP_Unified_API_Snippets 13 | { 14 | class GroupSnippets 15 | { 16 | const string serviceEndpoint = "https://graph.microsoft.com/v1.0/"; 17 | 18 | // Returns all of the groups in your tenant's directory. 19 | public static async Task> GetGroupsAsync() 20 | { 21 | var groups = new List(); 22 | JObject jResult = null; 23 | 24 | try 25 | { 26 | HttpClient client = new HttpClient(); 27 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 28 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 29 | 30 | // Endpoint for all groups in the tenant 31 | Uri groupsEndpoint = new Uri(serviceEndpoint + "myOrganization/groups"); 32 | 33 | HttpResponseMessage response = await client.GetAsync(groupsEndpoint); 34 | 35 | if (response.IsSuccessStatusCode) 36 | { 37 | string responseContent = await response.Content.ReadAsStringAsync(); 38 | jResult = JObject.Parse(responseContent); 39 | 40 | foreach (JObject group in jResult["value"]) 41 | { 42 | string groupId = (string)group["id"]; 43 | groups.Add(groupId); 44 | Debug.WriteLine("Got group: " + groupId); 45 | } 46 | } 47 | 48 | else 49 | { 50 | Debug.WriteLine("We could not get groups. The request returned this status code: " + response.StatusCode); 51 | return null; 52 | } 53 | 54 | return groups; 55 | 56 | } 57 | 58 | catch (Exception e) 59 | { 60 | Debug.WriteLine("We could not get groups: " + e.Message); 61 | return null; 62 | } 63 | 64 | } 65 | 66 | 67 | // Returns the display name of a specific group. 68 | public static async Task GetGroupAsync(string groupId) 69 | { 70 | string groupName = null; 71 | JObject jResult = null; 72 | 73 | try 74 | { 75 | HttpClient client = new HttpClient(); 76 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 77 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 78 | 79 | // Endpoint for the specified group 80 | Uri groupEndpoint = new Uri(serviceEndpoint + "myOrganization/groups/" + groupId); 81 | 82 | HttpResponseMessage response = await client.GetAsync(groupEndpoint); 83 | 84 | if (response.IsSuccessStatusCode) 85 | { 86 | string responseContent = await response.Content.ReadAsStringAsync(); 87 | jResult = JObject.Parse(responseContent); 88 | groupName = (string)jResult["displayName"]; 89 | Debug.WriteLine("Got group: " + groupName); 90 | } 91 | 92 | else 93 | { 94 | Debug.WriteLine("We could not get the specified group. The request returned this status code: " + response.StatusCode); 95 | return null; 96 | } 97 | 98 | } 99 | 100 | 101 | catch (Exception e) 102 | { 103 | Debug.WriteLine("We could not get the specified group: " + e.Message); 104 | return null; 105 | 106 | } 107 | 108 | return groupName; 109 | } 110 | 111 | public static async Task> GetGroupMembersAsync(string groupId) 112 | { 113 | var members = new List(); 114 | JObject jResult = null; 115 | 116 | try 117 | { 118 | HttpClient client = new HttpClient(); 119 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 120 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 121 | 122 | // Endpoint for all members of the specified group 123 | Uri membersEndpoint = new Uri(serviceEndpoint + "myOrganization/groups/" + groupId + "/members"); 124 | 125 | HttpResponseMessage response = await client.GetAsync(membersEndpoint); 126 | 127 | if (response.IsSuccessStatusCode) 128 | { 129 | string responseContent = await response.Content.ReadAsStringAsync(); 130 | jResult = JObject.Parse(responseContent); 131 | 132 | foreach (JObject member in jResult["value"]) 133 | { 134 | string userName = (string)member["displayName"]; 135 | members.Add(userName); 136 | Debug.WriteLine("Got member: " + userName); 137 | } 138 | 139 | } 140 | 141 | else 142 | { 143 | Debug.WriteLine("We could not get the group members. The request returned this status code: " + response.StatusCode); 144 | return null; 145 | 146 | } 147 | } 148 | 149 | catch (Exception e) 150 | { 151 | Debug.WriteLine("We could not get the group members: " + e.Message); 152 | return null; 153 | } 154 | 155 | return members; 156 | 157 | } 158 | 159 | public static async Task> GetGroupOwnersAsync(string groupId) 160 | { 161 | var owners = new List(); 162 | JObject jResult = null; 163 | 164 | try 165 | { 166 | HttpClient client = new HttpClient(); 167 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 168 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 169 | 170 | // Endpoint for all owners of the specified group 171 | Uri ownersEndpoint = new Uri(serviceEndpoint + "myOrganization/groups/" + groupId + "/owners"); 172 | 173 | HttpResponseMessage response = await client.GetAsync(ownersEndpoint); 174 | 175 | if (response.IsSuccessStatusCode) 176 | { 177 | string responseContent = await response.Content.ReadAsStringAsync(); 178 | jResult = JObject.Parse(responseContent); 179 | 180 | foreach (JObject member in jResult["value"]) 181 | { 182 | string userName = (string)member["displayName"]; 183 | owners.Add(userName); 184 | Debug.WriteLine("Got owner: " + userName); 185 | } 186 | 187 | } 188 | 189 | else 190 | { 191 | Debug.WriteLine("We could not get the group owners. The request returned this status code: " + response.StatusCode); 192 | return null; 193 | 194 | } 195 | } 196 | 197 | catch (Exception e) 198 | { 199 | Debug.WriteLine("We could not get the group owners: " + e.Message); 200 | return null; 201 | } 202 | 203 | return owners; 204 | 205 | } 206 | 207 | 208 | // Creates a new security group in the tenant. 209 | public static async Task CreateGroupAsync(string groupName) 210 | { 211 | JObject jResult = null; 212 | string createdGroupId = null; 213 | try 214 | { 215 | HttpClient client = new HttpClient(); 216 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 217 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 218 | 219 | // Endpoint for all groups in an organization 220 | Uri groupsEndpoint = new Uri(serviceEndpoint + "myOrganization/groups"); 221 | 222 | // Build contents of post body and convert to StringContent object. 223 | // Using line breaks for readability. 224 | 225 | string postBody = "{'mailEnabled':false," // Must be false, because only pure security groups can be created with the unified API. 226 | + "'displayName':'Group " + groupName + "'," 227 | + "'mailNickName':'" + groupName + "'," 228 | + "'securityEnabled':true" // Must be true, because only pure security groups can be created with the unified API. 229 | + "}"; 230 | 231 | var createBody = new StringContent(postBody, System.Text.Encoding.UTF8, "application/json"); 232 | 233 | HttpResponseMessage response = await client.PostAsync(groupsEndpoint, createBody); 234 | 235 | if (response.IsSuccessStatusCode) 236 | { 237 | string responseContent = await response.Content.ReadAsStringAsync(); 238 | jResult = JObject.Parse(responseContent); 239 | createdGroupId = (string)jResult["id"]; 240 | Debug.WriteLine("Created group: " + createdGroupId); 241 | } 242 | 243 | else 244 | { 245 | Debug.WriteLine("We could not create a group. The request returned this status code: " + response.StatusCode); 246 | return null; 247 | } 248 | 249 | } 250 | 251 | catch (Exception e) 252 | { 253 | Debug.WriteLine("We could not create a group: " + e.Message); 254 | return null; 255 | } 256 | 257 | return createdGroupId; 258 | 259 | } 260 | 261 | 262 | // Updates the description of an existing group. 263 | public static async Task UpdateGroupAsync(string groupId) 264 | { 265 | bool groupUpdated = false; 266 | 267 | try 268 | { 269 | HttpClient client = new HttpClient(); 270 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 271 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 272 | 273 | // Endpoint for all the specified group. 274 | Uri groupEndpoint = new Uri(serviceEndpoint + "myOrganization/groups/" + groupId); 275 | 276 | string updateBody = "{ 'Description': 'This is an updated group group.' }"; 277 | var patchBody = new StringContent(updateBody, System.Text.Encoding.UTF8, "application/json"); 278 | 279 | // Construct HTTP PATCH request 280 | 281 | var method = new HttpMethod("PATCH"); 282 | var request = new HttpRequestMessage(method, groupEndpoint) { Content = patchBody }; 283 | 284 | HttpResponseMessage response = await client.SendAsync(request); 285 | 286 | if (response.IsSuccessStatusCode) 287 | { 288 | groupUpdated = true; 289 | Debug.WriteLine("Updated group: " + groupId); 290 | } 291 | 292 | else 293 | { 294 | Debug.WriteLine("We could not update the group. The request returned this status code: " + response.StatusCode); 295 | groupUpdated = false; 296 | } 297 | 298 | } 299 | 300 | catch (Exception e) 301 | { 302 | Debug.WriteLine("We could not update the group: " + e.Message); 303 | groupUpdated = false; 304 | } 305 | 306 | return groupUpdated; 307 | 308 | } 309 | 310 | 311 | // Deletes an existing group in the tenant. 312 | public static async Task DeleteGroupAsync(string groupId) 313 | { 314 | bool eventDeleted = false; 315 | 316 | try 317 | { 318 | HttpClient client = new HttpClient(); 319 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 320 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 321 | 322 | // Endpoint for the specified group 323 | Uri eventEndpoint = new Uri(serviceEndpoint + "myOrganization/groups/" + groupId); 324 | 325 | HttpResponseMessage response = await client.DeleteAsync(eventEndpoint); 326 | 327 | if (response.IsSuccessStatusCode) 328 | { 329 | eventDeleted = true; 330 | Debug.WriteLine("Deleted group: " + groupId); 331 | } 332 | 333 | else 334 | { 335 | Debug.WriteLine("We could not delete the group. The request returned this status code: " + response.StatusCode); 336 | eventDeleted = false; 337 | } 338 | 339 | } 340 | 341 | catch (Exception e) 342 | { 343 | Debug.WriteLine("We could not delete the group: " + e.Message); 344 | eventDeleted = false; 345 | } 346 | 347 | return eventDeleted; 348 | 349 | } 350 | 351 | } 352 | } 353 | 354 | 355 | //********************************************************* 356 | // 357 | //O365-UWP-Microsoft-Graph-Snippets, https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets 358 | // 359 | //Copyright (c) Microsoft Corporation 360 | //All rights reserved. 361 | // 362 | // MIT License: 363 | // Permission is hereby granted, free of charge, to any person obtaining 364 | // a copy of this software and associated documentation files (the 365 | // ""Software""), to deal in the Software without restriction, including 366 | // without limitation the rights to use, copy, modify, merge, publish, 367 | // distribute, sublicense, and/or sell copies of the Software, and to 368 | // permit persons to whom the Software is furnished to do so, subject to 369 | // the following conditions: 370 | 371 | // The above copyright notice and this permission notice shall be 372 | // included in all copies or substantial portions of the Software. 373 | 374 | // THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, 375 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 376 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 377 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 378 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 379 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 380 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 381 | // 382 | //********************************************************* -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Groups/GroupStories.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using Windows.Storage; 9 | 10 | 11 | namespace O365_UWP_Unified_API_Snippets 12 | { 13 | class GroupStories 14 | { 15 | 16 | private static readonly string STORY_DATA_IDENTIFIER = Guid.NewGuid().ToString(); 17 | 18 | public static async Task TryGetGroupsAsync() 19 | { 20 | var groups = await GroupSnippets.GetGroupsAsync(); 21 | return groups != null; 22 | } 23 | 24 | public static async Task TryGetGroupAsync() 25 | { 26 | var groups = await GroupSnippets.GetGroupsAsync(); 27 | var groupId = groups[0]; 28 | var groupName = await GroupSnippets.GetGroupAsync(groupId); 29 | return groupName != null; 30 | } 31 | 32 | public static async Task TryGetGroupMembersAsync() 33 | { 34 | // Get all groups, then pass the first group id from the list. 35 | var groups = await GroupSnippets.GetGroupsAsync(); 36 | var groupId = groups[0]; 37 | var members = await GroupSnippets.GetGroupMembersAsync(groupId); 38 | return members != null; 39 | } 40 | 41 | public static async Task TryGetGroupOwnersAsync() 42 | { 43 | // Get all groups, then pass the first group id from the list. 44 | var groups = await GroupSnippets.GetGroupsAsync(); 45 | var groupId = groups[0]; 46 | var members = await GroupSnippets.GetGroupOwnersAsync(groupId); 47 | return members != null; 48 | } 49 | 50 | public static async Task TryCreateGroupAsync() 51 | { 52 | string createdGroup = await GroupSnippets.CreateGroupAsync(STORY_DATA_IDENTIFIER); 53 | return createdGroup != null; 54 | } 55 | 56 | public static async Task TryUpdateGroupAsync() 57 | { 58 | // Create an group first, then update it. 59 | string createdGroup = await GroupSnippets.CreateGroupAsync(STORY_DATA_IDENTIFIER); 60 | return await GroupSnippets.UpdateGroupAsync(createdGroup); 61 | } 62 | 63 | public static async Task TryDeleteGroupAsync() 64 | { 65 | // Create a group first, then delete it. 66 | string createdGroup = await GroupSnippets.CreateGroupAsync(STORY_DATA_IDENTIFIER); 67 | return await GroupSnippets.DeleteGroupAsync(createdGroup); 68 | } 69 | 70 | } 71 | } 72 | 73 | 74 | 75 | //********************************************************* 76 | // 77 | //O365-UWP-Microsoft-Graph-Snippets, https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets 78 | // 79 | //Copyright (c) Microsoft Corporation 80 | //All rights reserved. 81 | // 82 | // MIT License: 83 | // Permission is hereby granted, free of charge, to any person obtaining 84 | // a copy of this software and associated documentation files (the 85 | // ""Software""), to deal in the Software without restriction, including 86 | // without limitation the rights to use, copy, modify, merge, publish, 87 | // distribute, sublicense, and/or sell copies of the Software, and to 88 | // permit persons to whom the Software is furnished to do so, subject to 89 | // the following conditions: 90 | 91 | // The above copyright notice and this permission notice shall be 92 | // included in all copies or substantial portions of the Software. 93 | 94 | // THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, 95 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 96 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 97 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 98 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 99 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 100 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 101 | // 102 | //********************************************************* -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/MainPage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/MainPage.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 2 | 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Collections.ObjectModel; 7 | using System.Diagnostics; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Runtime.InteropServices.WindowsRuntime; 11 | using System.Threading.Tasks; 12 | using Windows.Foundation; 13 | using Windows.Foundation.Collections; 14 | using Windows.UI.Xaml; 15 | using Windows.UI.Xaml.Controls; 16 | using Windows.UI.Xaml.Controls.Primitives; 17 | using Windows.UI.Xaml.Data; 18 | using Windows.UI.Xaml.Input; 19 | using Windows.UI.Xaml.Media; 20 | using Windows.UI.Xaml.Navigation; 21 | using Microsoft.Identity.Client; 22 | 23 | // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 24 | 25 | namespace O365_UWP_Unified_API_Snippets 26 | { 27 | /// 28 | /// An empty page that can be used on its own or navigated to within a Frame. 29 | /// 30 | public sealed partial class MainPage : Page 31 | { 32 | public List StoryCollection { get; private set; } 33 | public MainPage() 34 | { 35 | this.InitializeComponent(); 36 | CreateStoryList(); 37 | Logger.LogCallback = delegate(Logger.LogLevel level, string message, bool pii) { Debug.WriteLine(level + " - " + message); }; 38 | Logger.Level = Logger.LogLevel.Info; 39 | } 40 | 41 | protected override void OnNavigatedTo(NavigationEventArgs e) 42 | { 43 | // Developer code - if you haven't registered the app yet, we warn you. 44 | if (!App.Current.Resources.ContainsKey("ida:ClientID")) 45 | { 46 | Debug.WriteLine("Oops - App not registered with Office 365. To run this sample, you must register it with Office 365. See Readme for more info."); 47 | 48 | } 49 | } 50 | private void CreateStoryList() 51 | { 52 | StoryCollection = new List(); 53 | 54 | // User stories 55 | 56 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Get Me", RunStoryAsync = UserStories.TryGetMeAsync }); 57 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Read Users", RunStoryAsync = UserStories.TryGetUsersAsync }); 58 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Create User", RunStoryAsync = UserStories.TryCreateUserAsync }); 59 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Get Drive", RunStoryAsync = UserStories.TryGetCurrentUserDriveAsync }); 60 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Get Events", RunStoryAsync = UserStories.TryGetEventsAsync }); 61 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Create Event", RunStoryAsync = UserStories.TryCreateEventAsync }); 62 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Update Event", RunStoryAsync = UserStories.TryUpdateEventAsync }); 63 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Delete Event", RunStoryAsync = UserStories.TryDeleteEventAsync }); 64 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Get Messages", RunStoryAsync = UserStories.TryGetMessages }); 65 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Send Message", RunStoryAsync = UserStories.TrySendMailAsync }); 66 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Get Manager", RunStoryAsync = UserStories.TryGetCurrentUserManagerAsync }); 67 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Get Directs", RunStoryAsync = UserStories.TryGetDirectReportsAsync }); 68 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Get Photo", RunStoryAsync = UserStories.TryGetCurrentUserPhotoAsync }); 69 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Get User Groups", RunStoryAsync = UserStories.TryGetCurrentUserGroupsAsync }); 70 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Get User Files", RunStoryAsync = UserStories.TryGetCurrentUserFilesAsync }); 71 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Create Text File", RunStoryAsync = UserStories.TryCreateFileAsync }); 72 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Download File", RunStoryAsync = UserStories.TryDownloadFileAsync }); 73 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Update File", RunStoryAsync = UserStories.TryUpdateFileAsync }); 74 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Rename File", RunStoryAsync = UserStories.TryRenameFileAsync }); 75 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Delete File", RunStoryAsync = UserStories.TryDeleteFileAsync }); 76 | StoryCollection.Add(new StoryDefinition() { GroupName = "Users", Title = "Create Folder", RunStoryAsync = UserStories.TryCreateFolderAsync }); 77 | 78 | // The following stories require your app to have permission to access your organization's directory. 79 | // Comment them if you're not going to run the app with that permission level. 80 | 81 | // Group stories 82 | 83 | StoryCollection.Add(new StoryDefinition() { GroupName = "Groups", Title = "Get All Groups", RunStoryAsync = GroupStories.TryGetGroupsAsync }); 84 | StoryCollection.Add(new StoryDefinition() { GroupName = "Groups", Title = "Get a Group", RunStoryAsync = GroupStories.TryGetGroupAsync }); 85 | StoryCollection.Add(new StoryDefinition() { GroupName = "Groups", Title = "Get Members", RunStoryAsync = GroupStories.TryGetGroupMembersAsync }); 86 | StoryCollection.Add(new StoryDefinition() { GroupName = "Groups", Title = "Get Owners", RunStoryAsync = GroupStories.TryGetGroupOwnersAsync }); 87 | StoryCollection.Add(new StoryDefinition() { GroupName = "Groups", Title = "Create Group", RunStoryAsync = GroupStories.TryCreateGroupAsync }); 88 | StoryCollection.Add(new StoryDefinition() { GroupName = "Groups", Title = "Update Group", RunStoryAsync = GroupStories.TryUpdateGroupAsync }); 89 | StoryCollection.Add(new StoryDefinition() { GroupName = "Groups", Title = "Delete Group", RunStoryAsync = GroupStories.TryDeleteGroupAsync }); 90 | 91 | 92 | // Organization stories 93 | 94 | StoryCollection.Add(new StoryDefinition() { GroupName = "Organization", Title = "Get Org Drives", RunStoryAsync = OrganizationStories.TryGetDrivesAsync }); 95 | 96 | // The Extensions stories require the admin-only AccessAsUser.All scope. Only admins can run these. 97 | // Uncomment that scope in AuthenticationHelper.cs if you want to run these. 98 | // Extensions stories 99 | 100 | StoryCollection.Add(new StoryDefinition() { GroupName = "Extensions", Title = "Set Open Extension", RunStoryAsync = ExtensionStories.TrySetOpenExtension}); 101 | StoryCollection.Add(new StoryDefinition() { GroupName = "Extensions", Title = "Get Open Extension", RunStoryAsync = ExtensionStories.TryGetOpenExtension }); 102 | StoryCollection.Add(new StoryDefinition() { GroupName = "Extensions", Title = "Register Schema Extension", RunStoryAsync = ExtensionStories.TryRegisterSchemaExtension }); 103 | StoryCollection.Add(new StoryDefinition() { GroupName = "Extensions", Title = "Get Schema Extension", RunStoryAsync = ExtensionStories.TryGetSchemaExtension }); 104 | StoryCollection.Add(new StoryDefinition() { GroupName = "Extensions", Title = "Set Schema Extension Value", RunStoryAsync = ExtensionStories.TrySetSchemaExtensionValue }); 105 | StoryCollection.Add(new StoryDefinition() { GroupName = "Extensions", Title = "Get Schema Extension Value", RunStoryAsync = ExtensionStories.TryGetSchemaExtensionValue }); 106 | StoryCollection.Add(new StoryDefinition() { GroupName = "Extensions", Title = "Delete Schema Extension", RunStoryAsync = ExtensionStories.TryDeleteSchemaExtension }); 107 | 108 | // Batching stories 109 | StoryCollection.Add(new StoryDefinition() { GroupName = "Batching", Title = "Parallel batch", RunStoryAsync = BatchingStories.TryRunParallelBatch }); 110 | StoryCollection.Add(new StoryDefinition() { GroupName = "Batching", Title = "Sequential batch", RunStoryAsync = BatchingStories.TryRunSequentialBatch }); 111 | 112 | var result = from story in StoryCollection group story by story.GroupName into api orderby api.Key select api; 113 | StoriesByApi.Source = result; 114 | } 115 | 116 | 117 | private async void RunSelectedStories_Click(object sender, RoutedEventArgs e) 118 | { 119 | 120 | await runSelectedAsync(); 121 | } 122 | 123 | private async Task runSelectedAsync() 124 | { 125 | ResetStories(); 126 | Stopwatch sw = new Stopwatch(); 127 | 128 | foreach (var story in StoryGrid.SelectedItems) 129 | { 130 | StoryDefinition currentStory = story as StoryDefinition; 131 | currentStory.IsRunning = true; 132 | sw.Restart(); 133 | bool result = false; 134 | try 135 | { 136 | result = await currentStory.RunStoryAsync(); 137 | Debug.WriteLine(String.Format("{0}.{1} {2}", currentStory.GroupName, currentStory.Title, (result) ? "passed" : "failed")); 138 | } 139 | catch (Exception ex) 140 | { 141 | Debug.WriteLine("{0}.{1} failed. Exception: {2}", currentStory.GroupName, currentStory.Title, ex.Message); 142 | result = false; 143 | 144 | } 145 | currentStory.Result = result; 146 | sw.Stop(); 147 | currentStory.DurationMS = sw.ElapsedMilliseconds; 148 | currentStory.IsRunning = false; 149 | 150 | 151 | } 152 | 153 | // To shut down this app when the Stories complete, uncomment the following line. 154 | // Application.Current.Exit(); 155 | } 156 | 157 | private void ResetStories() 158 | { 159 | foreach (var story in StoryCollection) 160 | { 161 | story.Result = null; 162 | story.DurationMS = null; 163 | } 164 | } 165 | 166 | private void ClearSelection_Click(object sender, RoutedEventArgs e) 167 | { 168 | StoryGrid.SelectedItems.Clear(); 169 | } 170 | 171 | private void Disconnect_Click(object sender, RoutedEventArgs e) 172 | { 173 | AuthenticationHelper.SignOut(); 174 | StoryGrid.SelectedItems.Clear(); 175 | } 176 | } 177 | } 178 | 179 | //********************************************************* 180 | // 181 | //O365-UWP-Microsoft-Graph-Snippets, https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets 182 | // 183 | //Copyright (c) Microsoft Corporation 184 | //All rights reserved. 185 | // 186 | // MIT License: 187 | // Permission is hereby granted, free of charge, to any person obtaining 188 | // a copy of this software and associated documentation files (the 189 | // "Software"), to deal in the Software without restriction, including 190 | // without limitation the rights to use, copy, modify, merge, publish, 191 | // distribute, sublicense, and/or sell copies of the Software, and to 192 | // permit persons to whom the Software is furnished to do so, subject to 193 | // the following conditions: 194 | 195 | // The above copyright notice and this permission notice shall be 196 | // included in all copies or substantial portions of the Software. 197 | 198 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 199 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 200 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 201 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 202 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 203 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 204 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 205 | // 206 | //********************************************************* -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/O365-UWP-Unified-API-Snippets.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x86 7 | {F947BB7C-4BA1-4466-AA73-29D7F1C3BC01} 8 | AppContainerExe 9 | Properties 10 | O365_UWP_Unified_API_Snippets 11 | O365-UWP-Unified-API-Snippets 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 | O365-UWP-Unified-API-Snippets_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 | 95 | 96 | 97 | App.xaml 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | MainPage.xaml 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | Designer 121 | 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 | -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/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 | 29 | 30 | -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/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 © 2015")] 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)] -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Properties/Default.rd.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/ResultToBrushConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 2 | 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 O365_UWP_Unified_API_Snippets 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 | // 46 | //O365-UWP-Microsoft-Graph-Snippets, https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets 47 | // 48 | //Copyright (c) Microsoft Corporation 49 | //All rights reserved. 50 | // 51 | // MIT License: 52 | // Permission is hereby granted, free of charge, to any person obtaining 53 | // a copy of this software and associated documentation files (the 54 | // "Software"), to deal in the Software without restriction, including 55 | // without limitation the rights to use, copy, modify, merge, publish, 56 | // distribute, sublicense, and/or sell copies of the Software, and to 57 | // permit persons to whom the Software is furnished to do so, subject to 58 | // the following conditions: 59 | 60 | // The above copyright notice and this permission notice shall be 61 | // included in all copies or substantial portions of the Software. 62 | 63 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 64 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 65 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 66 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 67 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 68 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 69 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 70 | // 71 | //********************************************************* 72 | -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/StoryDefinition.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace O365_UWP_Unified_API_Snippets 10 | { 11 | public class StoryDefinition : ViewModelBase 12 | { 13 | public string GroupName { get; set; } 14 | public string Title { get; set; } 15 | 16 | // Delegate method to call 17 | public Func> RunStoryAsync { get; set; } 18 | 19 | bool _isRunning = false; 20 | public bool IsRunning 21 | { 22 | get 23 | { 24 | return _isRunning; 25 | } 26 | set 27 | { 28 | SetProperty(ref _isRunning, value); 29 | } 30 | } 31 | 32 | bool? _result = null; 33 | public bool? Result 34 | { 35 | get 36 | { 37 | return _result; 38 | } 39 | set 40 | { 41 | SetProperty(ref _result, value); 42 | } 43 | } 44 | 45 | long? _durationMS = 0; 46 | public long? DurationMS 47 | { 48 | get 49 | { 50 | return _durationMS; 51 | } 52 | set 53 | { 54 | SetProperty(ref _durationMS, value); 55 | } 56 | } 57 | 58 | } 59 | 60 | public class TestGroup 61 | { 62 | public string GroupTitle { get; set; } 63 | public List Tests { get; set; } 64 | } 65 | } 66 | 67 | //********************************************************* 68 | // 69 | //O365-UWP-Microsoft-Graph-Snippets, https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets 70 | // 71 | //Copyright (c) Microsoft Corporation 72 | //All rights reserved. 73 | // 74 | // MIT License: 75 | // Permission is hereby granted, free of charge, to any person obtaining 76 | // a copy of this software and associated documentation files (the 77 | // "Software"), to deal in the Software without restriction, including 78 | // without limitation the rights to use, copy, modify, merge, publish, 79 | // distribute, sublicense, and/or sell copies of the Software, and to 80 | // permit persons to whom the Software is furnished to do so, subject to 81 | // the following conditions: 82 | 83 | // The above copyright notice and this permission notice shall be 84 | // included in all copies or substantial portions of the Software. 85 | 86 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 87 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 88 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 89 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 90 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 91 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 92 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 93 | // 94 | //********************************************************* -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Users/UserSnippets.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 2 | 3 | using Newtonsoft.Json.Linq; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Diagnostics; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Net.Http; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | using Windows.Storage; 13 | 14 | namespace O365_UWP_Unified_API_Snippets 15 | { 16 | class UserSnippets 17 | { 18 | const string serviceEndpoint = "https://graph.microsoft.com/v1.0/"; 19 | public static ApplicationDataContainer _settings = ApplicationData.Current.RoamingSettings; 20 | 21 | // Returns information about the signed-in user from Azure Active Directory. 22 | public static async Task GetMeAsync() 23 | { 24 | string currentUser = null; 25 | JObject jResult = null; 26 | 27 | try 28 | { 29 | HttpClient client = new HttpClient(); 30 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 31 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 32 | 33 | // Endpoint for all users in an organization 34 | Uri usersEndpoint = new Uri(serviceEndpoint + "me"); 35 | 36 | HttpResponseMessage response = await client.GetAsync(usersEndpoint); 37 | 38 | if (response.IsSuccessStatusCode) 39 | { 40 | string responseContent = await response.Content.ReadAsStringAsync(); 41 | jResult = JObject.Parse(responseContent); 42 | currentUser = (string)jResult["displayName"]; 43 | Debug.WriteLine("Got user: " + currentUser); 44 | } 45 | 46 | else 47 | { 48 | Debug.WriteLine("We could not get the current user. The request returned this status code: " + response.StatusCode); 49 | return null; 50 | } 51 | 52 | } 53 | 54 | 55 | catch (Exception e) 56 | { 57 | Debug.WriteLine("We could not get the current user: " + e.Message); 58 | return null; 59 | 60 | } 61 | 62 | return currentUser; 63 | } 64 | 65 | 66 | // Returns all of the users in the directory of the signed-in user's tenant. 67 | public static async Task> GetUsersAsync() 68 | { 69 | var users = new List(); 70 | JObject jResult = null; 71 | 72 | try 73 | { 74 | HttpClient client = new HttpClient(); 75 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 76 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 77 | 78 | // Endpoint for all users in an organization 79 | Uri usersEndpoint = new Uri(serviceEndpoint + "myOrganization/users"); 80 | 81 | HttpResponseMessage response = await client.GetAsync(usersEndpoint); 82 | 83 | if (response.IsSuccessStatusCode) 84 | { 85 | string responseContent = await response.Content.ReadAsStringAsync(); 86 | jResult = JObject.Parse(responseContent); 87 | 88 | foreach (JObject user in jResult["value"]) 89 | { 90 | string userName = (string)user["displayName"]; 91 | users.Add(userName); 92 | Debug.WriteLine("Got user: " + userName); 93 | } 94 | } 95 | 96 | else 97 | { 98 | Debug.WriteLine("We could not get users. The request returned this status code: " + response.StatusCode); 99 | return null; 100 | } 101 | 102 | return users; 103 | 104 | } 105 | 106 | catch (Exception e) 107 | { 108 | Debug.WriteLine("We could not get users: " + e.Message); 109 | return null; 110 | } 111 | 112 | 113 | } 114 | 115 | // Creates a new user in the signed-in user's tenant. This snippet requires an admin account. 116 | public static async Task CreateUserAsync(string userName) 117 | { 118 | JObject jResult = null; 119 | string createdUserName = null; 120 | 121 | // Get email domain from current user's email address. 122 | string currentUserEmail = (string)_settings.Values["userEmail"]; 123 | string[] splitString = currentUserEmail.Split('@'); 124 | string emailDomain = splitString[1]; 125 | 126 | try 127 | { 128 | HttpClient client = new HttpClient(); 129 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 130 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 131 | 132 | // Endpoint for all users in an organization 133 | Uri usersEndpoint = new Uri(serviceEndpoint + "myOrganization/users"); 134 | 135 | // Build contents of post body and convert to StringContent object. 136 | // Using line breaks for readability. 137 | 138 | string postBody = "{'accountEnabled':true," 139 | + "'displayName':'User " + userName + "'," 140 | + "'mailNickName':'" + userName + "'," 141 | + "'passwordProfile': {'password': 'pass@word1'}," 142 | + "'userPrincipalName':'" + userName + "@" + emailDomain + "'}"; 143 | 144 | var createBody = new StringContent(postBody, System.Text.Encoding.UTF8, "application/json"); 145 | 146 | HttpResponseMessage response = await client.PostAsync(usersEndpoint, createBody); 147 | 148 | if (response.IsSuccessStatusCode) 149 | { 150 | string responseContent = await response.Content.ReadAsStringAsync(); 151 | jResult = JObject.Parse(responseContent); 152 | createdUserName = (string)jResult["displayName"]; 153 | Debug.WriteLine("Created user: " + createdUserName); 154 | } 155 | 156 | else 157 | { 158 | Debug.WriteLine("We could not create a user. The request returned this status code: " + response.StatusCode); 159 | return null; 160 | } 161 | 162 | } 163 | 164 | catch (Exception e) 165 | { 166 | Debug.WriteLine("We could not create a user: " + e.Message); 167 | return null; 168 | } 169 | 170 | return createdUserName; 171 | 172 | } 173 | 174 | // Gets the signed-in user's drive. 175 | public static async Task GetCurrentUserDriveAsync() 176 | { 177 | string currentUserDriveId = null; 178 | JObject jResult = null; 179 | 180 | try 181 | { 182 | HttpClient client = new HttpClient(); 183 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 184 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 185 | 186 | // Endpoint for the current user's drive 187 | Uri usersEndpoint = new Uri(serviceEndpoint + "me/drive"); 188 | 189 | HttpResponseMessage response = await client.GetAsync(usersEndpoint); 190 | 191 | if (response.IsSuccessStatusCode) 192 | { 193 | string responseContent = await response.Content.ReadAsStringAsync(); 194 | jResult = JObject.Parse(responseContent); 195 | currentUserDriveId = (string)jResult["id"]; 196 | Debug.WriteLine("Got user drive: " + currentUserDriveId); 197 | } 198 | 199 | else 200 | { 201 | Debug.WriteLine("We could not get the current user drive. The request returned this status code: " + response.StatusCode); 202 | return null; 203 | } 204 | 205 | } 206 | 207 | 208 | catch (Exception e) 209 | { 210 | Debug.WriteLine("We could not get the current user drive: " + e.Message); 211 | return null; 212 | 213 | } 214 | 215 | return currentUserDriveId; 216 | 217 | } 218 | 219 | // Gets the signed-in user's calendar events. 220 | 221 | public static async Task> GetEventsAsync() 222 | { 223 | var events = new List(); 224 | JObject jResult = null; 225 | 226 | try 227 | { 228 | HttpClient client = new HttpClient(); 229 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 230 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 231 | 232 | // Endpoint for the current user's events 233 | Uri usersEndpoint = new Uri(serviceEndpoint + "me/events"); 234 | 235 | HttpResponseMessage response = await client.GetAsync(usersEndpoint); 236 | 237 | if (response.IsSuccessStatusCode) 238 | { 239 | string responseContent = await response.Content.ReadAsStringAsync(); 240 | jResult = JObject.Parse(responseContent); 241 | 242 | foreach (JObject calendarEvent in jResult["value"]) 243 | { 244 | string eventId = (string)calendarEvent["Id"]; 245 | events.Add(eventId); 246 | Debug.WriteLine("Got event: " + eventId); 247 | } 248 | 249 | } 250 | 251 | else 252 | { 253 | Debug.WriteLine("We could not get the current user's events. The request returned this status code: " + response.StatusCode); 254 | return null; 255 | 256 | } 257 | } 258 | 259 | catch (Exception e) 260 | { 261 | Debug.WriteLine("We could not get the current user's events: " + e.Message); 262 | return null; 263 | } 264 | 265 | return events; 266 | } 267 | 268 | // Creates a new event in the signed-in user's tenant. 269 | // Important note: This will create a user with a weak password. Consider deleting this user after you run the sample. 270 | public static async Task CreateEventAsync() 271 | { 272 | JObject jResult = null; 273 | string createdEventId = null; 274 | try 275 | { 276 | HttpClient client = new HttpClient(); 277 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 278 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 279 | 280 | // Endpoint for the current user's events 281 | Uri eventsEndpoint = new Uri(serviceEndpoint + "me/events"); 282 | 283 | // Build contents of post body and convert to StringContent object. 284 | // Using line breaks for readability. 285 | 286 | // Specifying the round-trip format specifier ("o") to the DateTimeOffset.ToString() method 287 | // so that the datetime string can be converted into an Edm.DateTimeOffset object: 288 | // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Roundtrip 289 | 290 | string postBody = "{'Subject':'Weekly Sync'," 291 | + "'Location':{'DisplayName':'Water Cooler'}," 292 | + "'Attendees':[{'Type':'Required','EmailAddress': {'Address':'mara@fabrikam.com'} }]," 293 | + "'Start': {'DateTime': '" + new DateTime(2014, 12, 1, 9, 30, 0).ToString("o") + "', 'TimeZone':'UTC'}," 294 | + "'End': {'DateTime': '" + new DateTime(2014, 12, 1, 10, 0, 0).ToString("o") + "', 'TimeZone':'UTC'}," 295 | + "'Body':{'Content': 'Status updates, blocking issues, and next steps.', 'ContentType':'Text'}}"; 296 | 297 | var createBody = new StringContent(postBody, System.Text.Encoding.UTF8, "application/json"); 298 | 299 | HttpResponseMessage response = await client.PostAsync(eventsEndpoint, createBody); 300 | 301 | if (response.IsSuccessStatusCode) 302 | { 303 | string responseContent = await response.Content.ReadAsStringAsync(); 304 | jResult = JObject.Parse(responseContent); 305 | createdEventId = (string)jResult["id"]; 306 | Debug.WriteLine("Created event: " + createdEventId); 307 | } 308 | 309 | else 310 | { 311 | Debug.WriteLine("We could not create an event. The request returned this status code: " + response.StatusCode); 312 | return null; 313 | } 314 | 315 | } 316 | 317 | catch (Exception e) 318 | { 319 | Debug.WriteLine("We could not create an event: " + e.Message); 320 | return null; 321 | } 322 | 323 | return createdEventId; 324 | 325 | } 326 | 327 | // Updates the subject of an existing event in the signed-in user's tenant. 328 | public static async Task UpdateEventAsync(string eventId) 329 | { 330 | bool eventUpdated = false; 331 | 332 | try 333 | { 334 | HttpClient client = new HttpClient(); 335 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 336 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 337 | 338 | // Endpoint for the specified event. 339 | Uri eventEndpoint = new Uri(serviceEndpoint + "me/events/" + eventId); 340 | 341 | string updateBody = "{ 'Subject': 'Sync of the Week' }"; 342 | var patchBody = new StringContent(updateBody, System.Text.Encoding.UTF8, "application/json"); 343 | 344 | // Construct HTTP PATCH request 345 | 346 | var method = new HttpMethod("PATCH"); 347 | var request = new HttpRequestMessage(method, eventEndpoint) { Content = patchBody }; 348 | 349 | HttpResponseMessage response = await client.SendAsync(request); 350 | 351 | if (response.IsSuccessStatusCode) 352 | { 353 | eventUpdated = true; 354 | Debug.WriteLine("Updated event: " + eventId); 355 | } 356 | 357 | else 358 | { 359 | Debug.WriteLine("We could not update the event. The request returned this status code: " + response.StatusCode); 360 | eventUpdated = false; 361 | } 362 | 363 | } 364 | 365 | catch (Exception e) 366 | { 367 | Debug.WriteLine("We could not update the event: " + e.Message); 368 | eventUpdated = false; 369 | } 370 | 371 | return eventUpdated; 372 | 373 | } 374 | 375 | // Deletes an existing event in the signed-in user's tenant. 376 | public static async Task DeleteEventAsync(string eventId) 377 | { 378 | bool eventDeleted = false; 379 | 380 | try 381 | { 382 | HttpClient client = new HttpClient(); 383 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 384 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 385 | 386 | // Endpoint for the specified event 387 | Uri eventEndpoint = new Uri(serviceEndpoint + "me/events/" + eventId); 388 | 389 | HttpResponseMessage response = await client.DeleteAsync(eventEndpoint); 390 | 391 | if (response.IsSuccessStatusCode) 392 | { 393 | eventDeleted = true; 394 | Debug.WriteLine("Deleted event: " + eventId); 395 | } 396 | 397 | else 398 | { 399 | Debug.WriteLine("We could not delete the event. The request returned this status code: " + response.StatusCode); 400 | eventDeleted = false; 401 | } 402 | 403 | } 404 | 405 | catch (Exception e) 406 | { 407 | Debug.WriteLine("We could not delete the event: " + e.Message); 408 | eventDeleted = false; 409 | } 410 | 411 | return eventDeleted; 412 | 413 | } 414 | 415 | // Returns the first page of the signed-in user's messages. 416 | public static async Task> GetMessagesAsync() 417 | { 418 | var messages = new List(); 419 | JObject jResult = null; 420 | 421 | try 422 | { 423 | HttpClient client = new HttpClient(); 424 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 425 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 426 | 427 | // Endpoint for all messages in the current user's mailbox 428 | Uri messagesEndpoint = new Uri(serviceEndpoint + "me/messages"); 429 | 430 | HttpResponseMessage response = await client.GetAsync(messagesEndpoint); 431 | 432 | if (response.IsSuccessStatusCode) 433 | { 434 | string responseContent = await response.Content.ReadAsStringAsync(); 435 | jResult = JObject.Parse(responseContent); 436 | 437 | foreach (JObject user in jResult["value"]) 438 | { 439 | string subject = (string)user["subject"]; 440 | messages.Add(subject); 441 | Debug.WriteLine("Got message: " + subject); 442 | } 443 | } 444 | 445 | else 446 | { 447 | Debug.WriteLine("We could not get messages. The request returned this status code: " + response.StatusCode); 448 | return null; 449 | } 450 | 451 | return messages; 452 | 453 | } 454 | 455 | catch (Exception e) 456 | { 457 | Debug.WriteLine("We could not get messages: " + e.Message); 458 | return null; 459 | } 460 | 461 | 462 | } 463 | 464 | // Updates the subject of an existing event in the signed-in user's tenant. 465 | public static async Task SendMessageAsync( 466 | string Subject, 467 | string Body, 468 | string RecipientAddress 469 | ) 470 | { 471 | bool emailSent = false; 472 | 473 | try 474 | { 475 | 476 | HttpClient client = new HttpClient(); 477 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 478 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 479 | 480 | // Endpoint for sending mail from the current user's mailbox 481 | Uri messageEndpoint = new Uri(serviceEndpoint + "me/microsoft.graph.sendmail"); 482 | 483 | 484 | string recipientJSON = "{'EmailAddress':{'Address':'" + RecipientAddress + "'}}"; 485 | 486 | // Build contents of post body and convert to StringContent object. 487 | // Using line breaks for readability. 488 | string postBody = "{'Message':{" 489 | + "'Body':{ " 490 | + "'Content': '" + Body + "'," 491 | + "'ContentType':'HTML'}," 492 | + "'Subject':'" + Subject + "'," 493 | + "'ToRecipients':[" + recipientJSON + "]}," 494 | + "'SaveToSentItems':true}"; 495 | 496 | var emailBody = new StringContent(postBody, System.Text.Encoding.UTF8, "application/json"); 497 | 498 | HttpResponseMessage response = await client.PostAsync(messageEndpoint, emailBody); 499 | 500 | if (!response.IsSuccessStatusCode) 501 | { 502 | 503 | Debug.WriteLine("We could not send the message. The request returned this status code: " + response.StatusCode); 504 | emailSent = false; 505 | } 506 | else 507 | { 508 | emailSent = true; 509 | } 510 | 511 | 512 | } 513 | 514 | catch (Exception e) 515 | { 516 | Debug.WriteLine("We could not send the message. The request returned this status code: " + e.Message); 517 | emailSent = false; 518 | } 519 | 520 | return emailSent; 521 | } 522 | 523 | // Gets the signed-in user's manager. 524 | public static async Task GetCurrentUserManagerAsync() 525 | { 526 | string currentUserManager = null; 527 | JObject jResult = null; 528 | 529 | try 530 | { 531 | HttpClient client = new HttpClient(); 532 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 533 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 534 | 535 | // Endpoint for the current user's manager 536 | Uri managerEndpoint = new Uri(serviceEndpoint + "me/manager"); 537 | 538 | HttpResponseMessage response = await client.GetAsync(managerEndpoint); 539 | 540 | if (response.IsSuccessStatusCode) 541 | { 542 | string responseContent = await response.Content.ReadAsStringAsync(); 543 | jResult = JObject.Parse(responseContent); 544 | currentUserManager = (string)jResult["displayName"]; 545 | Debug.WriteLine("Got manager: " + currentUserManager); 546 | } 547 | 548 | else 549 | { 550 | Debug.WriteLine("We could not get the current user's manager. The request returned this status code: " + response.StatusCode); 551 | return null; 552 | } 553 | 554 | } 555 | 556 | 557 | catch (Exception e) 558 | { 559 | Debug.WriteLine("We could not get the current user's manager: " + e.Message); 560 | return null; 561 | 562 | } 563 | 564 | return currentUserManager; 565 | 566 | } 567 | 568 | // Gets the signed-in user's direct reports. 569 | public static async Task> GetDirectReportsAsync() 570 | { 571 | var directReports = new List(); 572 | JObject jResult = null; 573 | 574 | try 575 | { 576 | HttpClient client = new HttpClient(); 577 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 578 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 579 | 580 | // Endpoint for the current user's direct reports 581 | Uri directsEndpoint = new Uri(serviceEndpoint + "me/directReports"); 582 | 583 | HttpResponseMessage response = await client.GetAsync(directsEndpoint); 584 | 585 | if (response.IsSuccessStatusCode) 586 | { 587 | string responseContent = await response.Content.ReadAsStringAsync(); 588 | jResult = JObject.Parse(responseContent); 589 | 590 | foreach (JObject user in jResult["value"]) 591 | { 592 | string userName = (string)user["displayName"]; 593 | directReports.Add(userName); 594 | Debug.WriteLine("Got direct report: " + userName); 595 | } 596 | } 597 | 598 | else 599 | { 600 | Debug.WriteLine("We could not get direct reports. The request returned this status code: " + response.StatusCode); 601 | return null; 602 | } 603 | 604 | return directReports; 605 | 606 | } 607 | 608 | catch (Exception e) 609 | { 610 | Debug.WriteLine("We could not get direct reports: " + e.Message); 611 | return null; 612 | } 613 | 614 | 615 | } 616 | 617 | 618 | // Gets the signed-in user's photo. 619 | public static async Task GetCurrentUserPhotoAsync() 620 | { 621 | string currentUserPhotoId = null; 622 | JObject jResult = null; 623 | 624 | try 625 | { 626 | HttpClient client = new HttpClient(); 627 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 628 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 629 | 630 | // Endpoint for the current user's photo 631 | Uri photoEndpoint = new Uri(serviceEndpoint + "me/photo"); 632 | 633 | HttpResponseMessage response = await client.GetAsync(photoEndpoint); 634 | 635 | if (response.IsSuccessStatusCode) 636 | { 637 | string responseContent = await response.Content.ReadAsStringAsync(); 638 | jResult = JObject.Parse(responseContent); 639 | currentUserPhotoId = (string)jResult["id"]; 640 | Debug.WriteLine("Got user photo: " + currentUserPhotoId); 641 | } 642 | 643 | else 644 | { 645 | Debug.WriteLine("We could not get the current user photo. The request returned this status code: " + response.StatusCode); 646 | return null; 647 | } 648 | 649 | } 650 | 651 | 652 | catch (Exception e) 653 | { 654 | Debug.WriteLine("We could not get the current user photo: " + e.Message); 655 | return null; 656 | 657 | } 658 | 659 | return currentUserPhotoId; 660 | 661 | } 662 | 663 | // Gets the groups that the signed-in user is a member of. 664 | public static async Task> GetCurrentUserGroupsAsync() 665 | { 666 | var memberOfGroups = new List(); 667 | JObject jResult = null; 668 | 669 | try 670 | { 671 | HttpClient client = new HttpClient(); 672 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 673 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 674 | 675 | // Endpoint for the current user's groups 676 | Uri memberOfEndpoint = new Uri(serviceEndpoint + "me/memberOf"); 677 | 678 | HttpResponseMessage response = await client.GetAsync(memberOfEndpoint); 679 | 680 | if (response.IsSuccessStatusCode) 681 | { 682 | string responseContent = await response.Content.ReadAsStringAsync(); 683 | jResult = JObject.Parse(responseContent); 684 | 685 | foreach (JObject group in jResult["value"]) 686 | { 687 | string groupId = (string)group["objectId"]; 688 | memberOfGroups.Add(groupId); 689 | Debug.WriteLine("Got group: " + groupId); 690 | } 691 | } 692 | 693 | else 694 | { 695 | Debug.WriteLine("We could not get user groups. The request returned this status code: " + response.StatusCode); 696 | return null; 697 | } 698 | 699 | return memberOfGroups; 700 | 701 | } 702 | 703 | catch (Exception e) 704 | { 705 | Debug.WriteLine("We could not get user groups: " + e.Message); 706 | return null; 707 | } 708 | 709 | 710 | } 711 | 712 | 713 | public static async Task> GetCurrentUserFilesAsync() 714 | { 715 | var files = new List(); 716 | JObject jResult = null; 717 | 718 | try 719 | { 720 | HttpClient client = new HttpClient(); 721 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 722 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 723 | 724 | // Endpoint for all files and folders for a user 725 | Uri filesEndpoint = new Uri(serviceEndpoint + "me/drive/root/children"); 726 | 727 | HttpResponseMessage response = await client.GetAsync(filesEndpoint); 728 | 729 | if (response.IsSuccessStatusCode) 730 | { 731 | string responseContent = await response.Content.ReadAsStringAsync(); 732 | jResult = JObject.Parse(responseContent); 733 | 734 | foreach (JObject file in jResult["value"]) 735 | { 736 | string fileName = (string)file["name"]; 737 | files.Add(fileName); 738 | Debug.WriteLine("Got file: " + fileName); 739 | } 740 | } 741 | 742 | else 743 | { 744 | Debug.WriteLine("We could not get user files. The request returned this status code: " + response.StatusCode); 745 | return null; 746 | } 747 | 748 | return files; 749 | 750 | } 751 | 752 | catch (Exception e) 753 | { 754 | Debug.WriteLine("We could not get user files: " + e.Message); 755 | return null; 756 | } 757 | 758 | 759 | } 760 | 761 | // Creates a text file in the user's root directory. 762 | public static async Task CreateFileAsync(string fileName, string fileContent) 763 | { 764 | string createdFileId = null; 765 | JObject jResult = null; 766 | 767 | try 768 | { 769 | 770 | HttpClient client = new HttpClient(); 771 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 772 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 773 | 774 | var fileContentPostBody = new StringContent(fileContent, System.Text.Encoding.UTF8, "text/plain"); 775 | 776 | // Endpoint for content in an existing file. 777 | Uri fileEndpoint = new Uri(serviceEndpoint + "me/drive/root/children/" + fileName + "/content"); 778 | 779 | var requestMessage = new HttpRequestMessage(HttpMethod.Put, fileEndpoint) 780 | { 781 | Content = fileContentPostBody 782 | }; 783 | 784 | 785 | HttpResponseMessage response = await client.SendAsync(requestMessage); 786 | 787 | if (response.IsSuccessStatusCode) 788 | { 789 | string responseContent = await response.Content.ReadAsStringAsync(); 790 | jResult = JObject.Parse(responseContent); 791 | createdFileId = (string)jResult["id"]; 792 | Debug.WriteLine("Created file Id: " + createdFileId); 793 | 794 | 795 | } 796 | else 797 | { 798 | Debug.WriteLine("We could not create the file. The request returned this status code: " + response.StatusCode); 799 | return null; 800 | } 801 | 802 | 803 | } 804 | 805 | catch (Exception e) 806 | { 807 | Debug.WriteLine("We could not create the file. The request returned this status code: " + e.Message); 808 | return null; 809 | } 810 | 811 | return createdFileId; 812 | } 813 | 814 | // Downloads the content of an existing file. 815 | public static async Task DownloadFileAsync(string fileId) 816 | { 817 | Stream fileContent = null; 818 | 819 | try 820 | { 821 | HttpClient client = new HttpClient(); 822 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 823 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 824 | 825 | // Endpoint for content in an existing file. Use "/me/drive/root/children//content" if you know the name but not the Id. 826 | Uri fileEndpoint = new Uri(serviceEndpoint + "me/drive/items/" + fileId + "/content"); 827 | 828 | HttpResponseMessage response = await client.GetAsync(fileEndpoint); 829 | 830 | if (response.IsSuccessStatusCode) 831 | { 832 | fileContent = await response.Content.ReadAsStreamAsync(); 833 | Debug.WriteLine("Downloaded file: " + fileId); 834 | 835 | 836 | } 837 | else 838 | { 839 | Debug.WriteLine("We could not download the file. The request returned this status code: " + response.StatusCode); 840 | return null; 841 | } 842 | 843 | 844 | } 845 | 846 | catch (Exception e) 847 | { 848 | Debug.WriteLine("We could not download the file. The request returned this status code: " + e.Message); 849 | return null; 850 | } 851 | 852 | return fileContent; 853 | } 854 | 855 | // Adds content to a file in the user's root directory. 856 | public static async Task UpdateFileAsync(string fileId, string fileContent) 857 | { 858 | bool fileUpdated = false; 859 | 860 | try 861 | { 862 | 863 | HttpClient client = new HttpClient(); 864 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 865 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 866 | 867 | var fileContentPostBody = new StringContent(fileContent, System.Text.Encoding.UTF8, "text/plain"); 868 | 869 | // Endpoint for content in an existing file. Use "/me/drive/root/children//content" if you know the name but not the Id. 870 | Uri fileEndpoint = new Uri(serviceEndpoint + "me/drive/items/" + fileId + "/content"); 871 | 872 | var requestMessage = new HttpRequestMessage(HttpMethod.Put, fileEndpoint) 873 | { 874 | Content = fileContentPostBody 875 | }; 876 | 877 | 878 | HttpResponseMessage response = await client.SendAsync(requestMessage); 879 | 880 | if (response.IsSuccessStatusCode) 881 | { 882 | fileUpdated = true; 883 | Debug.WriteLine("Updated file Id: " + fileId); 884 | 885 | } 886 | else 887 | { 888 | Debug.WriteLine("We could not update the file. The request returned this status code: " + response.StatusCode); 889 | fileUpdated = false; 890 | } 891 | 892 | 893 | } 894 | 895 | catch (Exception e) 896 | { 897 | Debug.WriteLine("We could not update the file. The request returned this status code: " + e.Message); 898 | fileUpdated = false; 899 | } 900 | 901 | return fileUpdated; 902 | } 903 | 904 | // Deletes a file in the user's root directory. 905 | public static async Task DeleteFileAsync(string fileId) 906 | { 907 | bool fileDeleted = false; 908 | 909 | try 910 | { 911 | 912 | HttpClient client = new HttpClient(); 913 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 914 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 915 | 916 | // Endpoint for the file to delete. 917 | Uri fileEndpoint = new Uri(serviceEndpoint + "me/drive/items/" + fileId); 918 | 919 | HttpResponseMessage response = await client.DeleteAsync(fileEndpoint); 920 | 921 | if (response.IsSuccessStatusCode) 922 | { 923 | fileDeleted = true; 924 | Debug.WriteLine("Deleted file Id: " + fileId); 925 | 926 | } 927 | else 928 | { 929 | Debug.WriteLine("We could not delete the file. The request returned this status code: " + response.StatusCode); 930 | fileDeleted = false; 931 | } 932 | 933 | 934 | } 935 | 936 | catch (Exception e) 937 | { 938 | Debug.WriteLine("We could not delete the file. The request returned this status code: " + e.Message); 939 | fileDeleted = false; 940 | } 941 | 942 | return fileDeleted; 943 | } 944 | 945 | // Renames a file in the user's root directory. 946 | public static async Task RenameFileAsync(string fileId, string newFileName) 947 | { 948 | bool fileCopied = false; 949 | 950 | try 951 | { 952 | 953 | HttpClient client = new HttpClient(); 954 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 955 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 956 | 957 | // Endpoint for the file to rename. 958 | Uri fileEndpoint = new Uri(serviceEndpoint + "me/drive/items/" + fileId); 959 | 960 | // Build contents of post body and convert to StringContent object. 961 | // Using line breaks for readability. 962 | string patchBody = "{" 963 | + "'name':'" + newFileName + "'}"; 964 | 965 | var copyBody = new StringContent(patchBody, System.Text.Encoding.UTF8, "application/json"); 966 | 967 | var method = new HttpMethod("PATCH"); 968 | 969 | var requestMessage = new HttpRequestMessage(method, fileEndpoint) 970 | { 971 | Content = copyBody 972 | }; 973 | 974 | HttpResponseMessage response = await client.SendAsync(requestMessage); 975 | 976 | if (response.IsSuccessStatusCode) 977 | { 978 | fileCopied = true; 979 | Debug.WriteLine("Renamed file Id: " + fileId); 980 | 981 | } 982 | else 983 | { 984 | Debug.WriteLine("We could not rename the file. The request returned this status code: " + response.StatusCode); 985 | fileCopied = false; 986 | } 987 | 988 | 989 | } 990 | 991 | catch (Exception e) 992 | { 993 | Debug.WriteLine("We could not rename the file. The request returned this status code: " + e.Message); 994 | fileCopied = false; 995 | } 996 | 997 | return fileCopied; 998 | } 999 | 1000 | 1001 | // Creates a folder in the user's root directory. 1002 | public static async Task CreateFolderAsync(string folderName) 1003 | { 1004 | string createFolderId = null; 1005 | JObject jResult = null; 1006 | 1007 | try 1008 | { 1009 | 1010 | HttpClient client = new HttpClient(); 1011 | var token = await AuthenticationHelper.GetTokenForUserAsync(); 1012 | client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 1013 | 1014 | // Endpoint for all files and folders for a user 1015 | Uri foldersEndpoint = new Uri(serviceEndpoint + "me/drive/root/children"); 1016 | 1017 | var folderMetadata = "{" 1018 | + "'name': '" + folderName + "'," 1019 | + "'folder': {}," 1020 | + "'@name.conflictBehavior': 'rename'" 1021 | + "}" 1022 | ; 1023 | 1024 | 1025 | var folderMetadataPostBody = new StringContent(folderMetadata, System.Text.Encoding.UTF8, "application/json"); 1026 | 1027 | HttpResponseMessage response = await client.PostAsync(foldersEndpoint, folderMetadataPostBody); 1028 | 1029 | if (response.IsSuccessStatusCode) 1030 | { 1031 | string responseContent = await response.Content.ReadAsStringAsync(); 1032 | jResult = JObject.Parse(responseContent); 1033 | createFolderId = (string)jResult["id"]; 1034 | Debug.WriteLine("Created folder Id: " + createFolderId); 1035 | 1036 | 1037 | } 1038 | else 1039 | { 1040 | Debug.WriteLine("We could not create the folder. The request returned this status code: " + response.StatusCode); 1041 | return null; 1042 | } 1043 | 1044 | 1045 | } 1046 | 1047 | catch (Exception e) 1048 | { 1049 | Debug.WriteLine("We could not create the folder. The request returned this status code: " + e.Message); 1050 | return null; 1051 | } 1052 | 1053 | return createFolderId; 1054 | } 1055 | 1056 | } 1057 | } 1058 | 1059 | //********************************************************* 1060 | // 1061 | //O365-UWP-Microsoft-Graph-Snippets, https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets 1062 | // 1063 | //Copyright (c) Microsoft Corporation 1064 | //All rights reserved. 1065 | // 1066 | // MIT License: 1067 | // Permission is hereby granted, free of charge, to any person obtaining 1068 | // a copy of this software and associated documentation files (the 1069 | // ""Software""), to deal in the Software without restriction, including 1070 | // without limitation the rights to use, copy, modify, merge, publish, 1071 | // distribute, sublicense, and/or sell copies of the Software, and to 1072 | // permit persons to whom the Software is furnished to do so, subject to 1073 | // the following conditions: 1074 | 1075 | // The above copyright notice and this permission notice shall be 1076 | // included in all copies or substantial portions of the Software. 1077 | 1078 | // THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, 1079 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1080 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1081 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 1082 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 1083 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 1084 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 1085 | // 1086 | //********************************************************* -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/Users/UserStories.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using Windows.Storage; 10 | 11 | namespace O365_UWP_Unified_API_Snippets 12 | { 13 | class UserStories 14 | { 15 | private static readonly string STORY_DATA_IDENTIFIER = Guid.NewGuid().ToString(); 16 | private static readonly string DEFAULT_MESSAGE_BODY = "This message was sent from the Office 365 UWP Unified API Snippets project"; 17 | public static ApplicationDataContainer _settings = ApplicationData.Current.RoamingSettings; 18 | 19 | public static async Task TryGetMeAsync() 20 | { 21 | var currentUser = await UserSnippets.GetMeAsync(); 22 | 23 | return currentUser != null; 24 | } 25 | 26 | public static async Task TryGetUsersAsync() 27 | { 28 | var users = await UserSnippets.GetUsersAsync(); 29 | return users != null; 30 | } 31 | 32 | public static async Task TryCreateUserAsync() 33 | { 34 | string createdUser = await UserSnippets.CreateUserAsync(STORY_DATA_IDENTIFIER); 35 | return createdUser != null; 36 | } 37 | 38 | public static async Task TryGetCurrentUserDriveAsync() 39 | { 40 | string driveId = await UserSnippets.GetCurrentUserDriveAsync(); 41 | return driveId != null; 42 | } 43 | 44 | public static async Task TryGetEventsAsync() 45 | { 46 | var events = await UserSnippets.GetEventsAsync(); 47 | return events != null; 48 | } 49 | 50 | public static async Task TryCreateEventAsync() 51 | { 52 | string createdEvent = await UserSnippets.CreateEventAsync(); 53 | return createdEvent != null; 54 | } 55 | 56 | public static async Task TryUpdateEventAsync() 57 | { 58 | // Create an event first, then update it. 59 | string createdEvent = await UserSnippets.CreateEventAsync(); 60 | return await UserSnippets.UpdateEventAsync(createdEvent); 61 | } 62 | 63 | public static async Task TryDeleteEventAsync() 64 | { 65 | // Create an event first, then delete it. 66 | string createdEvent = await UserSnippets.CreateEventAsync(); 67 | return await UserSnippets.DeleteEventAsync(createdEvent); 68 | } 69 | 70 | public static async Task TryGetMessages() 71 | { 72 | var messages = await UserSnippets.GetMessagesAsync(); 73 | return messages != null; 74 | } 75 | 76 | public static async Task TrySendMailAsync() 77 | { 78 | return await UserSnippets.SendMessageAsync( 79 | STORY_DATA_IDENTIFIER, 80 | DEFAULT_MESSAGE_BODY, 81 | (string)_settings.Values["userEmail"] 82 | ); 83 | } 84 | 85 | public static async Task TryGetCurrentUserManagerAsync() 86 | { 87 | string managerName = await UserSnippets.GetCurrentUserManagerAsync(); 88 | return managerName != null; 89 | } 90 | 91 | public static async Task TryGetDirectReportsAsync() 92 | { 93 | var users = await UserSnippets.GetDirectReportsAsync(); 94 | return users != null; 95 | } 96 | 97 | public static async Task TryGetCurrentUserPhotoAsync() 98 | { 99 | string photoId = await UserSnippets.GetCurrentUserPhotoAsync(); 100 | return photoId != null; 101 | } 102 | 103 | public static async Task TryGetCurrentUserGroupsAsync() 104 | { 105 | var groups = await UserSnippets.GetCurrentUserGroupsAsync(); 106 | return groups != null; 107 | } 108 | 109 | public static async Task TryGetCurrentUserFilesAsync() 110 | { 111 | var files = await UserSnippets.GetCurrentUserFilesAsync(); 112 | return files != null; 113 | } 114 | 115 | public static async Task TryCreateFileAsync() 116 | { 117 | var createdFileId = await UserSnippets.CreateFileAsync(Guid.NewGuid().ToString(), STORY_DATA_IDENTIFIER); 118 | return createdFileId != null; 119 | } 120 | 121 | public static async Task TryDownloadFileAsync() 122 | { 123 | var createdFileId = await UserSnippets.CreateFileAsync(Guid.NewGuid().ToString(), STORY_DATA_IDENTIFIER); 124 | var fileContent = await UserSnippets.DownloadFileAsync(createdFileId); 125 | return fileContent != null; 126 | } 127 | 128 | public static async Task TryUpdateFileAsync() 129 | { 130 | var createdFileId = await UserSnippets.CreateFileAsync(Guid.NewGuid().ToString(), STORY_DATA_IDENTIFIER); 131 | return await UserSnippets.UpdateFileAsync(createdFileId, STORY_DATA_IDENTIFIER); 132 | } 133 | 134 | public static async Task TryRenameFileAsync() 135 | { 136 | var newFileName = Guid.NewGuid().ToString(); 137 | var createdFileId = await UserSnippets.CreateFileAsync(Guid.NewGuid().ToString(), STORY_DATA_IDENTIFIER); 138 | return await UserSnippets.RenameFileAsync(createdFileId, newFileName); 139 | } 140 | 141 | public static async Task TryDeleteFileAsync() 142 | { 143 | var fileName = Guid.NewGuid().ToString(); 144 | var createdFileId = await UserSnippets.CreateFileAsync(Guid.NewGuid().ToString(), STORY_DATA_IDENTIFIER); 145 | return await UserSnippets.DeleteFileAsync(createdFileId); 146 | } 147 | 148 | public static async Task TryCreateFolderAsync() 149 | { 150 | var createdFolderId = await UserSnippets.CreateFolderAsync(Guid.NewGuid().ToString()); 151 | return createdFolderId != null; 152 | } 153 | } 154 | } 155 | 156 | 157 | //********************************************************* 158 | // 159 | //O365-UWP-Microsoft-Graph-Snippets, https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets 160 | // 161 | //Copyright (c) Microsoft Corporation 162 | //All rights reserved. 163 | // 164 | // MIT License: 165 | // Permission is hereby granted, free of charge, to any person obtaining 166 | // a copy of this software and associated documentation files (the 167 | // ""Software""), to deal in the Software without restriction, including 168 | // without limitation the rights to use, copy, modify, merge, publish, 169 | // distribute, sublicense, and/or sell copies of the Software, and to 170 | // permit persons to whom the Software is furnished to do so, subject to 171 | // the following conditions: 172 | 173 | // The above copyright notice and this permission notice shall be 174 | // included in all copies or substantial portions of the Software. 175 | 176 | // THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, 177 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 178 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 179 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 180 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 181 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 182 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 183 | // 184 | //********************************************************* -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/ViewModelBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 2 | 3 | using System; 4 | using System.ComponentModel; 5 | using System.Runtime.CompilerServices; 6 | 7 | namespace O365_UWP_Unified_API_Snippets 8 | { 9 | /// 10 | /// Base view model for working with the unified API. 11 | /// 12 | public class ViewModelBase : INotifyPropertyChanged 13 | { 14 | 15 | protected bool SetProperty(ref T field, T value, [CallerMemberName] string propertyName = "") 16 | { 17 | // If the value is the same as the current value, return false to indicate this was a no-op. 18 | if (Object.Equals(field, value)) 19 | return false; 20 | 21 | // Raise any registered property changed events, and indicate to the user that the value was indeed changed. 22 | field = value; 23 | NotifyPropertyChanged(propertyName); 24 | return true; 25 | } 26 | 27 | public event PropertyChangedEventHandler PropertyChanged; 28 | 29 | 30 | protected void NotifyPropertyChanged([CallerMemberName]string propertyName = "") 31 | { 32 | if (PropertyChanged != null) 33 | PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 34 | } 35 | } 36 | } 37 | //********************************************************* 38 | // 39 | //O365-UWP-Microsoft-Graph-Snippets, https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets 40 | // 41 | //Copyright (c) Microsoft Corporation 42 | //All rights reserved. 43 | // 44 | // MIT License: 45 | // Permission is hereby granted, free of charge, to any person obtaining 46 | // a copy of this software and associated documentation files (the 47 | // "Software"), to deal in the Software without restriction, including 48 | // without limitation the rights to use, copy, modify, merge, publish, 49 | // distribute, sublicense, and/or sell copies of the Software, and to 50 | // permit persons to whom the Software is furnished to do so, subject to 51 | // the following conditions: 52 | 53 | // The above copyright notice and this permission notice shall be 54 | // included in all copies or substantial portions of the Software. 55 | 56 | // THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, 57 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 58 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 59 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 60 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 61 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 62 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 63 | // 64 | //********************************************************* -------------------------------------------------------------------------------- /O365-UWP-Unified-API-Snippets/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "Microsoft.Identity.Client": "1.1.0-preview", 4 | "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0", 5 | "Newtonsoft.Json": "7.0.1" 6 | }, 7 | "frameworks": { 8 | "uap10.0": {} 9 | }, 10 | "runtimes": { 11 | "win10-arm": {}, 12 | "win10-arm-aot": {}, 13 | "win10-x86": {}, 14 | "win10-x86-aot": {}, 15 | "win10-x64": {}, 16 | "win10-x64-aot": {} 17 | } 18 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Microsoft Graph UWP Snippets Sample (REST) 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 | * [How the sample affects your tenant data](#how-the-sample-affects-your-tenant-data) 16 | * [How to run the extensions snippets](#extensions-snippets) 17 | * [Questions and comments](#questions) 18 | * [Additional resources](#additional-resources) 19 | 20 | 21 | ## Introduction 22 | 23 | This sample shows how to use the Microsoft Graph API to send email, manage groups, and perform other activities with Office 365 data. 24 | Microsoft Graph exposes multiple APIs from Microsoft cloud services through a single REST API endpoint. 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. 25 | 26 | 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://azure.microsoft.com/en-us/documentation/articles/active-directory-appmodel-v2-overview), which enables developers to write a single code flow that handles authentication for both work or school (Azure Active Directory) and personal (Microsoft) accounts. 27 | 28 | ## Important Note about the MSAL Preview 29 | 30 | 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. 31 | 32 | **Note:** This 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. You can also use a test account. 33 | 34 | 35 | ## Prerequisites ## 36 | 37 | This sample requires the following: 38 | 39 | * [Visual Studio 2015](https://www.visualstudio.com/en-us/downloads) 40 | * Windows 10 ([development mode enabled](https://msdn.microsoft.com/library/windows/apps/xaml/dn706236.aspx)) 41 | * 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). 42 | 43 | 44 | ## Register and configure the app 45 | 46 | 1. Sign into the [App Registration Portal](https://apps.dev.microsoft.com/) using either your personal or work or school account. 47 | 2. Select **Add an app**. 48 | 3. Enter a name for the app, and select **Create application**. 49 | 50 | The registration page displays, listing the properties of your app. 51 | 52 | 4. Under **Platforms**, select **Add platform**. 53 | 5. Select **Native Application**. 54 | 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. 55 | 56 | 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. 57 | 58 | 7. Select **Save**. 59 | 60 | 61 | ## Build and debug ## 62 | 63 | **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. 64 | 65 | 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. 66 | ![Office 365 UWP Microsoft Graph connect sample](/readme-images/appId_and_redirectURI.png "Client ID value in App.xaml file")` 67 | 68 | 2. Press F5 to build and debug. Run the solution and sign in with either your personal or work or school account. 69 | 70 | 71 | ##How the sample affects your tenant data 72 | This sample runs REST commands that create, read, update, or delete data. When running commands that delete or edit data, the sample creates fake entities. The fake entities are deleted or edited so that your actual tenant data is unaffected. The sample will leave behind fake entities on your tenant. 73 | 74 | 75 | ##How to run the extensions snippets 76 | This sample contains snippets that show you how to work with [custom extensions](https://dev.office.com/blogs/adding-customer-data-to-resources-in-Microsoft-Graph-preview). This feature is currently in preview. 77 | 78 | These snippets require the admin-only **AccessAsUser.All** scope, so in order to run them you'll need to uncomment that scope string in the `AuthenticationHelper.cs` file. 79 | 80 | Additionally, these snippets will run only on a tenant that has a verified domain. You specify the name of this domain by making it the value of the `domainName` string in the `ExtensionSnippets.cs` file: 81 | 82 | const string domainName = "your verified domain"; 83 | 84 | 85 | ## Contributing ## 86 | 87 | If you'd like to contribute to this sample, see [CONTRIBUTING.MD](/CONTRIBUTING.md). 88 | 89 | 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. 90 | 91 | 92 | ## Questions and comments 93 | 94 | We'd love to get your feedback about the O365 UWP Microsoft Graph Snippets project. You can send your questions and suggestions to us in the [Issues](https://github.com/OfficeDev/O365-UWP-Microsoft-Graph-Snippets/issues) section of this repository. 95 | 96 | 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] and [office365]. 97 | 98 | 99 | ## Additional resources ## 100 | 101 | - [Other Office 365 Connect samples](https://github.com/OfficeDev?utf8=%E2%9C%93&query=-Connect) 102 | - [Microsoft Graph overview](http://graph.microsoft.io) 103 | - [Office 365 APIs platform overview](https://msdn.microsoft.com/office/office365/howto/platform-development-overview) 104 | - [Office 365 API code samples and videos](https://msdn.microsoft.com/office/office365/howto/starter-projects-and-code-samples) 105 | - [Office developer code samples](http://dev.office.com/code-samples) 106 | - [Office dev center](http://dev.office.com/) 107 | 108 | 109 | ## Copyright 110 | Copyright (c) 2017 Microsoft. All rights reserved. 111 | 112 | 113 | -------------------------------------------------------------------------------- /readme-images/ClientTenant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-rest-sample/36c03fb66affd60eb818bdd8ec4bafa380660a15/readme-images/ClientTenant.png -------------------------------------------------------------------------------- /readme-images/appId_and_redirectURI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-rest-sample/36c03fb66affd60eb818bdd8ec4bafa380660a15/readme-images/appId_and_redirectURI.png -------------------------------------------------------------------------------- /readme-images/copy_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/uwp-csharp-snippets-rest-sample/36c03fb66affd60eb818bdd8ec4bafa380660a15/readme-images/copy_icon.png --------------------------------------------------------------------------------