├── .gitattributes
├── .github
├── ISSUE_TEMPLATE
│ ├── ask-a-question.md
│ └── bug_report.md
├── dependabot.yml
├── policies
│ └── resourceManagement.yml
└── workflows
│ ├── auto-merge-dependabot.yml
│ └── msbuild.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── GraphTutorial
├── App.xaml
├── App.xaml.cs
├── Assets
│ ├── LockScreenLogo.scale-200.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
├── CalendarPage.xaml
├── CalendarPage.xaml.cs
├── GraphDateTimeTimeZoneConverter.cs
├── GraphTutorial.csproj
├── GraphTutorial.sln
├── HomePage.xaml
├── HomePage.xaml.cs
├── MainPage.xaml
├── MainPage.xaml.cs
├── NewEventPage.xaml
├── NewEventPage.xaml.cs
├── OAuth.resw.example
├── Package.appxmanifest
└── Properties
│ ├── AssemblyInfo.cs
│ └── Default.rd.xml
├── LICENSE
├── README.md
└── SECURITY.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/ask-a-question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Ask a question
3 | about: Ask a question about Graph, adding features to this sample, etc.
4 | title: ''
5 | labels: question, needs triage
6 | assignees: ''
7 |
8 | ---
9 |
10 | Thank you for taking an interest in Microsoft Graph development! Please feel free to ask a question here, but keep in mind the following:
11 |
12 | - This is not an official Microsoft support channel, and our ability to respond to questions here is limited. Questions about Graph, or questions about adding a new feature to the sample, will be answered on a best-effort basis.
13 | - Questions should be asked on [Stack Overflow](https://stackoverflow.com/questions/tagged/microsoft-graph).
14 | - Issues with Microsoft Graph itself should be handled through [support](https://developer.microsoft.com/graph/support).
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug report, needs triage
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Where did you get the code?**
11 | - [ ] Downloaded from GitHub
12 | - [ ] Downloaded from the [Microsoft Graph quick start tool](https://developer.microsoft.com/graph/quick-start)
13 | - [ ] Followed the tutorial from [Microsoft Graph tutorials](https://docs.microsoft.com/graph/tutorials)
14 |
15 | **Describe the bug**
16 | A clear and concise description of what the bug is.
17 |
18 | **To Reproduce**
19 | Steps to reproduce the behavior:
20 | 1. Go to '...'
21 | 2. Click on '....'
22 | 3. Scroll down to '....'
23 | 4. See error
24 |
25 | **Expected behavior**
26 | A clear and concise description of what you expected to happen.
27 |
28 | **Screenshots**
29 | If applicable, add screenshots to help explain your problem.
30 |
31 | **Desktop (please complete the following information):**
32 | - OS: [e.g. iOS]
33 | - Browser [e.g. chrome, safari]
34 | - Version [e.g. 22]
35 |
36 | **Dependency versions**
37 | - Authentication library (MSAL, etc.) version:
38 | - Graph library (Graph SDK, REST library, etc.) version:
39 |
40 | **Additional context**
41 | Add any other context about the problem here.
42 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "nuget" # See documentation for possible values
9 | directory: "/GraphTutorial" # Location of package manifests
10 | schedule:
11 | interval: "weekly"
12 |
--------------------------------------------------------------------------------
/.github/policies/resourceManagement.yml:
--------------------------------------------------------------------------------
1 | id:
2 | name: GitOps.PullRequestIssueManagement
3 | description: GitOps.PullRequestIssueManagement primitive
4 | owner:
5 | resource: repository
6 | disabled: false
7 | where:
8 | configuration:
9 | resourceManagementConfiguration:
10 | scheduledSearches:
11 | - description:
12 | frequencies:
13 | - hourly:
14 | hour: 6
15 | filters:
16 | - isIssue
17 | - isOpen
18 | - hasLabel:
19 | label: needs author feedback
20 | - hasLabel:
21 | label: no recent activity
22 | - noActivitySince:
23 | days: 3
24 | actions:
25 | - closeIssue
26 | - description:
27 | frequencies:
28 | - hourly:
29 | hour: 6
30 | filters:
31 | - isIssue
32 | - isOpen
33 | - hasLabel:
34 | label: needs author feedback
35 | - noActivitySince:
36 | days: 4
37 | - isNotLabeledWith:
38 | label: no recent activity
39 | actions:
40 | - addLabel:
41 | label: no recent activity
42 | - addReply:
43 | reply: This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for **4 days**. It will be closed if no further activity occurs **within 3 days of this comment**.
44 | - description:
45 | frequencies:
46 | - hourly:
47 | hour: 6
48 | filters:
49 | - isIssue
50 | - isOpen
51 | - hasLabel:
52 | label: duplicate
53 | - noActivitySince:
54 | days: 1
55 | actions:
56 | - addReply:
57 | reply: This issue has been marked as duplicate and has not had any activity for **1 day**. It will be closed for housekeeping purposes.
58 | - closeIssue
59 | - description:
60 | frequencies:
61 | - hourly:
62 | hour: 3
63 | filters:
64 | - isOpen
65 | - isIssue
66 | - hasLabel:
67 | label: graph question
68 | actions:
69 | - removeLabel:
70 | label: 'needs attention :wave:'
71 | - removeLabel:
72 | label: needs author feedback
73 | - removeLabel:
74 | label: 'needs triage :mag:'
75 | - removeLabel:
76 | label: no recent activity
77 | - addLabel:
78 | label: out of scope
79 | - addReply:
80 | reply: >-
81 | It looks like you are asking a question about using Microsoft Graph or one of the Microsoft Graph SDKs that is not directly related to this sample. Unfortunately we are not set up to answer general questions in this repository, so this issue will be closed.
82 |
83 |
84 | Please try asking your question on [Stack Overflow](https://stackoverflow.com/questions/tagged/microsoft-graph-api), tagging your question with `microsoft-graph-api`.
85 | - closeIssue
86 | - description:
87 | frequencies:
88 | - hourly:
89 | hour: 3
90 | filters:
91 | - isOpen
92 | - isIssue
93 | - hasLabel:
94 | label: graph issue
95 | actions:
96 | - removeLabel:
97 | label: 'needs attention :wave:'
98 | - removeLabel:
99 | label: needs author feedback
100 | - removeLabel:
101 | label: 'needs triage :mag:'
102 | - removeLabel:
103 | label: no recent activity
104 | - addLabel:
105 | label: out of scope
106 | - addReply:
107 | reply: >-
108 | It looks like you are reporting an issue with Microsoft Graph or one of the Microsoft Graph SDKs that is not fixable by changing code in this sample. Unfortunately we are not set up to provide product support in this repository, so this issue will be closed.
109 |
110 |
111 | Please visit one of the following links to report your issue.
112 |
113 |
114 | - Issue with Microsoft Graph service: [Microsoft Graph support](https://developer.microsoft.com/graph/support#report-issues-with-the-service), choose one of the options under **Report issues with the service**
115 |
116 | - Issue with a Microsoft Graph SDK: Open an issue in the SDK's GitHub repository. See [microsoftgraph on GitHub](https://github.com/microsoftgraph?q=sdk+in%3Aname&type=public&language=) for a list of SDK repositories.
117 | - closeIssue
118 | eventResponderTasks:
119 | - if:
120 | - payloadType: Issue_Comment
121 | - isAction:
122 | action: Created
123 | - isActivitySender:
124 | issueAuthor: True
125 | - hasLabel:
126 | label: needs author feedback
127 | - isOpen
128 | then:
129 | - addLabel:
130 | label: 'needs attention :wave:'
131 | - removeLabel:
132 | label: needs author feedback
133 | description:
134 | - if:
135 | - payloadType: Issues
136 | - not:
137 | isAction:
138 | action: Closed
139 | - hasLabel:
140 | label: no recent activity
141 | then:
142 | - removeLabel:
143 | label: no recent activity
144 | description:
145 | - if:
146 | - payloadType: Issue_Comment
147 | - hasLabel:
148 | label: no recent activity
149 | then:
150 | - removeLabel:
151 | label: no recent activity
152 | description:
153 | - if:
154 | - payloadType: Pull_Request
155 | then:
156 | - inPrLabel:
157 | label: in pr
158 | description:
159 | onFailure:
160 | onSuccess:
161 |
--------------------------------------------------------------------------------
/.github/workflows/auto-merge-dependabot.yml:
--------------------------------------------------------------------------------
1 | name: Auto-merge dependabot updates
2 |
3 | on:
4 | pull_request:
5 | branches: [ main ]
6 |
7 | permissions:
8 | pull-requests: write
9 | contents: write
10 |
11 | jobs:
12 |
13 | dependabot-merge:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | if: ${{ github.actor == 'dependabot[bot]' }}
18 |
19 | steps:
20 | - name: Dependabot metadata
21 | id: metadata
22 | uses: dependabot/fetch-metadata@v1.1.1
23 | with:
24 | github-token: "${{ secrets.GITHUB_TOKEN }}"
25 |
26 | - name: Enable auto-merge for Dependabot PRs
27 | if: ${{steps.metadata.outputs.update-type != 'version-update:semver-major'}}
28 | run: gh pr merge --auto --merge "$PR_URL"
29 | env:
30 | PR_URL: ${{github.event.pull_request.html_url}}
31 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
32 |
--------------------------------------------------------------------------------
/.github/workflows/msbuild.yml:
--------------------------------------------------------------------------------
1 | name: MSBuild
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 | workflow_dispatch:
9 |
10 | env:
11 | # Path to the solution file relative to the root of the project.
12 | SOLUTION_FILE_PATH: .\GraphTutorial
13 |
14 | # Configuration type to build.
15 | # You can convert this to a build matrix if you need coverage of multiple configuration types.
16 | # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
17 | BUILD_CONFIGURATION: Debug
18 |
19 | permissions:
20 | contents: read
21 |
22 | jobs:
23 | build:
24 | runs-on: windows-latest
25 |
26 | steps:
27 | - uses: actions/checkout@v3
28 |
29 | - name: Copy settings file
30 | run: |
31 | copy ${{env.SOLUTION_FILE_PATH}}\OAuth.resw.example ${{env.SOLUTION_FILE_PATH}}\OAuth.resw
32 |
33 | - name: Add MSBuild to PATH
34 | uses: microsoft/setup-msbuild@v1.0.2
35 |
36 | - name: Restore NuGet packages
37 | working-directory: ${{env.GITHUB_WORKSPACE}}
38 | run: nuget restore ${{env.SOLUTION_FILE_PATH}}
39 |
40 | - name: Build
41 | working-directory: ${{env.GITHUB_WORKSPACE}}
42 | # Add additional options to the MSBuild command line here (like platform or verbosity level).
43 | # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
44 | run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}}
45 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # User-specific files
2 | *.suo
3 | *.user
4 | *.sln.docstates
5 | .vs/
6 |
7 | # Build results
8 | [Dd]ebug/
9 | [Dd]ebugPublic/
10 | [Rr]elease/
11 | x64/
12 | build/
13 | bld/
14 | [Bb]in/
15 | [Oo]bj/
16 |
17 | # MSTest test Results
18 | [Tt]est[Rr]esult*/
19 | [Bb]uild[Ll]og.*
20 |
21 | #NUNIT
22 | *.VisualState.xml
23 | TestResult.xml
24 |
25 | # Build Results of an ATL Project
26 | [Dd]ebugPS/
27 | [Rr]eleasePS/
28 | dlldata.c
29 |
30 | *_i.c
31 | *_p.c
32 | *_i.h
33 | *.ilk
34 | *.meta
35 | *.obj
36 | *.pch
37 | *.pdb
38 | *.pgc
39 | *.pgd
40 | *.rsp
41 | *.sbr
42 | *.tlb
43 | *.tli
44 | *.tlh
45 | *.tmp
46 | *.tmp_proj
47 | *.log
48 | *.vspscc
49 | *.vssscc
50 | .builds
51 | *.pidb
52 | *.svclog
53 | *.scc
54 |
55 | # Chutzpah Test files
56 | _Chutzpah*
57 |
58 | # Visual C++ cache files
59 | ipch/
60 | *.aps
61 | *.ncb
62 | *.opensdf
63 | *.sdf
64 | *.cachefile
65 |
66 | # Visual Studio profiler
67 | *.psess
68 | *.vsp
69 | *.vspx
70 |
71 | # TFS 2012 Local Workspace
72 | $tf/
73 |
74 | # Guidance Automation Toolkit
75 | *.gpState
76 |
77 | # ReSharper is a .NET coding add-in
78 | _ReSharper*/
79 | *.[Rr]e[Ss]harper
80 | *.DotSettings.user
81 |
82 | # JustCode is a .NET coding addin-in
83 | .JustCode
84 |
85 | # TeamCity is a build add-in
86 | _TeamCity*
87 |
88 | # DotCover is a Code Coverage Tool
89 | *.dotCover
90 |
91 | # NCrunch
92 | *.ncrunch*
93 | _NCrunch_*
94 | .*crunch*.local.xml
95 |
96 | # MightyMoose
97 | *.mm.*
98 | AutoTest.Net/
99 |
100 | # Web workbench (sass)
101 | .sass-cache/
102 |
103 | # Installshield output folder
104 | [Ee]xpress/
105 |
106 | # DocProject is a documentation generator add-in
107 | DocProject/buildhelp/
108 | DocProject/Help/*.HxT
109 | DocProject/Help/*.HxC
110 | DocProject/Help/*.hhc
111 | DocProject/Help/*.hhk
112 | DocProject/Help/*.hhp
113 | DocProject/Help/Html2
114 | DocProject/Help/html
115 |
116 | # Click-Once directory
117 | publish/
118 |
119 | # Publish Web Output
120 | *.[Pp]ublish.xml
121 | *.azurePubxml
122 |
123 | # NuGet Packages Directory
124 | packages/
125 | ## TODO: If the tool you use requires repositories.config uncomment the next line
126 | #!packages/repositories.config
127 |
128 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
129 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented)
130 | !packages/build/
131 |
132 | # Windows Azure Build Output
133 | csx/
134 | *.build.csdef
135 |
136 | # Windows Store app package directory
137 | AppPackages/
138 |
139 | # Others
140 | sql/
141 | *.Cache
142 | ClientBin/
143 | [Ss]tyle[Cc]op.*
144 | ~$*
145 | *~
146 | *.dbmdl
147 | *.dbproj.schemaview
148 | *.publishsettings
149 | node_modules/
150 |
151 | # RIA/Silverlight projects
152 | Generated_Code/
153 |
154 | # Backup & report files from converting an old project file to a newer
155 | # Visual Studio version. Backup files are not needed, because we have git ;-)
156 | _UpgradeReport_Files/
157 | Backup*/
158 | UpgradeLog*.XML
159 | UpgradeLog*.htm
160 |
161 | # SQL Server files
162 | *.mdf
163 | *.ldf
164 |
165 | # Business Intelligence projects
166 | *.rdl.data
167 | *.bim.layout
168 | *.bim_*.settings
169 |
170 | # Microsoft Fakes
171 | FakesAssemblies/
172 |
173 | # MacOS files
174 | **.DS_Store
175 |
176 | ## VS Code
177 | .vscode/
178 |
179 | ## OAuth settings
180 | OAuth.resw
181 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Microsoft Open Source Code of Conduct
2 |
3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
4 |
5 | Resources:
6 |
7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
10 | - Employees can reach out at [aka.ms/opensource/moderation-support](https://aka.ms/opensource/moderation-support)
11 |
--------------------------------------------------------------------------------
/GraphTutorial/App.xaml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/GraphTutorial/App.xaml.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation.
2 | // Licensed under the MIT License.
3 |
4 | using System;
5 | using Windows.ApplicationModel;
6 | using Windows.ApplicationModel.Activation;
7 | using Windows.UI.Xaml;
8 | using Windows.UI.Xaml.Controls;
9 | using Windows.UI.Xaml.Navigation;
10 |
11 | namespace GraphTutorial
12 | {
13 | ///
14 | /// Provides application-specific behavior to supplement the default Application class.
15 | ///
16 | sealed partial class App : Application
17 | {
18 | public bool IsAuthenticated { get; set; }
19 |
20 | ///
21 | /// Initializes the singleton application object. This is the first line of authored code
22 | /// executed, and as such is the logical equivalent of main() or WinMain().
23 | ///
24 | public App()
25 | {
26 | this.InitializeComponent();
27 | this.Suspending += OnSuspending;
28 | }
29 |
30 | ///
31 | /// Invoked when the application is launched normally by the end user. Other entry points
32 | /// will be used such as when the application is launched to open a specific file.
33 | ///
34 | /// Details about the launch request and process.
35 | protected override void OnLaunched(LaunchActivatedEventArgs e)
36 | {
37 | Frame rootFrame = Window.Current.Content as Frame;
38 |
39 | // Do not repeat app initialization when the Window already has content,
40 | // just ensure that the window is active
41 | if (rootFrame == null)
42 | {
43 | // Create a Frame to act as the navigation context and navigate to the first page
44 | rootFrame = new Frame();
45 |
46 | rootFrame.NavigationFailed += OnNavigationFailed;
47 |
48 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
49 | {
50 | //TODO: Load state from previously suspended application
51 | }
52 |
53 | // Place the frame in the current Window
54 | Window.Current.Content = rootFrame;
55 | }
56 |
57 | if (e.PrelaunchActivated == false)
58 | {
59 | if (rootFrame.Content == null)
60 | {
61 | // When the navigation stack isn't restored navigate to the first page,
62 | // configuring the new page by passing required information as a navigation
63 | // parameter
64 | rootFrame.Navigate(typeof(MainPage), e.Arguments);
65 | }
66 | // Ensure the current window is active
67 | Window.Current.Activate();
68 | }
69 | }
70 |
71 | ///
72 | /// Invoked when Navigation to a certain page fails
73 | ///
74 | /// The Frame which failed navigation
75 | /// Details about the navigation failure
76 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
77 | {
78 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
79 | }
80 |
81 | ///
82 | /// Invoked when application execution is being suspended. Application state is saved
83 | /// without knowing whether the application will be terminated or resumed with the contents
84 | /// of memory still intact.
85 | ///
86 | /// The source of the suspend request.
87 | /// Details about the suspend request.
88 | private void OnSuspending(object sender, SuspendingEventArgs e)
89 | {
90 | var deferral = e.SuspendingOperation.GetDeferral();
91 | //TODO: Save application state and stop any background activity
92 | deferral.Complete();
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/GraphTutorial/Assets/LockScreenLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/msgraph-sample-uwp/ff29d6db40c5ac0c09b55b71ce9d728f2be23601/GraphTutorial/Assets/LockScreenLogo.scale-200.png
--------------------------------------------------------------------------------
/GraphTutorial/Assets/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/msgraph-sample-uwp/ff29d6db40c5ac0c09b55b71ce9d728f2be23601/GraphTutorial/Assets/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/GraphTutorial/Assets/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/msgraph-sample-uwp/ff29d6db40c5ac0c09b55b71ce9d728f2be23601/GraphTutorial/Assets/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/GraphTutorial/Assets/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/msgraph-sample-uwp/ff29d6db40c5ac0c09b55b71ce9d728f2be23601/GraphTutorial/Assets/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/GraphTutorial/Assets/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/msgraph-sample-uwp/ff29d6db40c5ac0c09b55b71ce9d728f2be23601/GraphTutorial/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/GraphTutorial/Assets/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/msgraph-sample-uwp/ff29d6db40c5ac0c09b55b71ce9d728f2be23601/GraphTutorial/Assets/StoreLogo.png
--------------------------------------------------------------------------------
/GraphTutorial/Assets/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/msgraph-sample-uwp/ff29d6db40c5ac0c09b55b71ce9d728f2be23601/GraphTutorial/Assets/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/GraphTutorial/CalendarPage.xaml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
26 |
27 |
32 |
37 |
38 |
43 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/GraphTutorial/CalendarPage.xaml.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation.
2 | // Licensed under the MIT License.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using CommunityToolkit.Authentication;
8 | using CommunityToolkit.Graph.Extensions;
9 | using Microsoft.Graph;
10 | using Microsoft.Toolkit.Uwp.UI.Controls;
11 | using Windows.UI.Xaml;
12 | using Windows.UI.Xaml.Controls;
13 | using Windows.UI.Xaml.Navigation;
14 |
15 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
16 |
17 | namespace GraphTutorial
18 | {
19 | ///
20 | /// An empty page that can be used on its own or navigated to within a Frame.
21 | ///
22 | public sealed partial class CalendarPage : Page
23 | {
24 | public CalendarPage()
25 | {
26 | this.InitializeComponent();
27 | }
28 |
29 | private void ShowNotification(string message)
30 | {
31 | // Get the main page that contains the InAppNotification
32 | var mainPage = (Window.Current.Content as Frame).Content as MainPage;
33 |
34 | // Get the notification control
35 | var notification = mainPage.FindName("Notification") as InAppNotification;
36 |
37 | notification.Show(message);
38 | }
39 |
40 | protected override async void OnNavigatedTo(NavigationEventArgs e)
41 | {
42 | // Get the Graph client from the provider
43 | var graphClient = ProviderManager.Instance.GlobalProvider.GetClient();
44 |
45 | try
46 | {
47 | // Get the user's mailbox settings to determine
48 | // their time zone
49 | var user = await graphClient.Me.Request()
50 | .Select(u => new { u.MailboxSettings })
51 | .GetAsync();
52 |
53 | var startOfWeek = GetUtcStartOfWeekInTimeZone(DateTime.Today, user.MailboxSettings.TimeZone);
54 | var endOfWeek = startOfWeek.AddDays(7);
55 |
56 | var queryOptions = new List
57 | {
58 | new QueryOption("startDateTime", startOfWeek.ToString("o")),
59 | new QueryOption("endDateTime", endOfWeek.ToString("o"))
60 | };
61 |
62 | // Get the events
63 | var events = await graphClient.Me.CalendarView.Request(queryOptions)
64 | .Header("Prefer", $"outlook.timezone=\"{user.MailboxSettings.TimeZone}\"")
65 | .Select(ev => new
66 | {
67 | ev.Subject,
68 | ev.Organizer,
69 | ev.Start,
70 | ev.End
71 | })
72 | .OrderBy("start/dateTime")
73 | .Top(50)
74 | .GetAsync();
75 |
76 | EventList.ItemsSource = events.CurrentPage.ToList();
77 | }
78 | catch (ServiceException ex)
79 | {
80 | ShowNotification($"Exception getting events: {ex.Message}");
81 | }
82 |
83 | base.OnNavigatedTo(e);
84 | }
85 |
86 | private static DateTime GetUtcStartOfWeekInTimeZone(DateTime today, string timeZoneId)
87 | {
88 | TimeZoneInfo userTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
89 |
90 | // Assumes Sunday as first day of week
91 | int diff = System.DayOfWeek.Sunday - today.DayOfWeek;
92 |
93 | // create date as unspecified kind
94 | var unspecifiedStart = DateTime.SpecifyKind(today.AddDays(diff), DateTimeKind.Unspecified);
95 |
96 | // convert to UTC
97 | return TimeZoneInfo.ConvertTimeToUtc(unspecifiedStart, userTimeZone);
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/GraphTutorial/GraphDateTimeTimeZoneConverter.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation.
2 | // Licensed under the MIT License.
3 |
4 | //
5 | using System;
6 | using Microsoft.Graph;
7 | using Microsoft.Graph.Extensions;
8 |
9 | namespace GraphTutorial
10 | {
11 | class GraphDateTimeTimeZoneConverter : Windows.UI.Xaml.Data.IValueConverter
12 | {
13 | public object Convert(object value, Type targetType, object parameter, string language)
14 | {
15 | DateTimeTimeZone date = value as DateTimeTimeZone;
16 |
17 | if (date != null)
18 | {
19 | return date.ToDateTime().ToString();
20 | }
21 |
22 | return string.Empty;
23 | }
24 |
25 | public object ConvertBack(object value, Type targetType, object parameter, string language)
26 | {
27 | throw new NotImplementedException();
28 | }
29 | }
30 | }
31 | //
32 |
--------------------------------------------------------------------------------
/GraphTutorial/GraphTutorial.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x86
7 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}
8 | AppContainerExe
9 | Properties
10 | GraphTutorial
11 | GraphTutorial
12 | en-US
13 | UAP
14 | 10.0.19041.0
15 | 10.0.17763.0
16 | 14
17 | 512
18 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
19 | true
20 | false
21 |
22 |
23 | true
24 | bin\x86\Debug\
25 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
26 | ;2008
27 | full
28 | x86
29 | false
30 | prompt
31 | true
32 |
33 |
34 | bin\x86\Release\
35 | TRACE;NETFX_CORE;WINDOWS_UWP
36 | true
37 | ;2008
38 | pdbonly
39 | x86
40 | false
41 | prompt
42 | true
43 | true
44 |
45 |
46 | true
47 | bin\ARM\Debug\
48 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
49 | ;2008
50 | full
51 | ARM
52 | false
53 | prompt
54 | true
55 |
56 |
57 | bin\ARM\Release\
58 | TRACE;NETFX_CORE;WINDOWS_UWP
59 | true
60 | ;2008
61 | pdbonly
62 | ARM
63 | false
64 | prompt
65 | true
66 | true
67 |
68 |
69 | true
70 | bin\ARM64\Debug\
71 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
72 | ;2008
73 | full
74 | ARM64
75 | false
76 | prompt
77 | true
78 | true
79 |
80 |
81 | bin\ARM64\Release\
82 | TRACE;NETFX_CORE;WINDOWS_UWP
83 | true
84 | ;2008
85 | pdbonly
86 | ARM64
87 | false
88 | prompt
89 | true
90 | true
91 |
92 |
93 | true
94 | bin\x64\Debug\
95 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
96 | ;2008
97 | full
98 | x64
99 | false
100 | prompt
101 | true
102 |
103 |
104 | bin\x64\Release\
105 | TRACE;NETFX_CORE;WINDOWS_UWP
106 | true
107 | ;2008
108 | pdbonly
109 | x64
110 | false
111 | prompt
112 | true
113 | true
114 |
115 |
116 | PackageReference
117 |
118 |
119 |
120 | App.xaml
121 |
122 |
123 | CalendarPage.xaml
124 |
125 |
126 |
127 | HomePage.xaml
128 |
129 |
130 | MainPage.xaml
131 |
132 |
133 | NewEventPage.xaml
134 |
135 |
136 |
137 |
138 |
139 | Designer
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | MSBuild:Compile
155 | Designer
156 |
157 |
158 | Designer
159 | MSBuild:Compile
160 |
161 |
162 | Designer
163 | MSBuild:Compile
164 |
165 |
166 | MSBuild:Compile
167 | Designer
168 |
169 |
170 | Designer
171 | MSBuild:Compile
172 |
173 |
174 |
175 |
176 | 7.1.4
177 |
178 |
179 | 7.1.4
180 |
181 |
182 | 6.2.14
183 |
184 |
185 | 7.1.3
186 |
187 |
188 | 7.1.3
189 |
190 |
191 | 7.1.3
192 |
193 |
194 |
195 |
196 |
197 |
198 | 14.0
199 |
200 |
201 |
208 |
--------------------------------------------------------------------------------
/GraphTutorial/GraphTutorial.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.3.32901.215
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphTutorial", "GraphTutorial.csproj", "{1359BDFF-04FF-4A5D-B55B-33E447D9FC52}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|ARM = Debug|ARM
11 | Debug|ARM64 = Debug|ARM64
12 | Debug|x64 = Debug|x64
13 | Debug|x86 = Debug|x86
14 | Release|ARM = Release|ARM
15 | Release|ARM64 = Release|ARM64
16 | Release|x64 = Release|x64
17 | Release|x86 = Release|x86
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|ARM.ActiveCfg = Debug|ARM
21 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|ARM.Build.0 = Debug|ARM
22 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|ARM.Deploy.0 = Debug|ARM
23 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|ARM64.ActiveCfg = Debug|ARM64
24 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|ARM64.Build.0 = Debug|ARM64
25 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|ARM64.Deploy.0 = Debug|ARM64
26 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|x64.ActiveCfg = Debug|x64
27 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|x64.Build.0 = Debug|x64
28 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|x64.Deploy.0 = Debug|x64
29 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|x86.ActiveCfg = Debug|x86
30 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|x86.Build.0 = Debug|x86
31 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Debug|x86.Deploy.0 = Debug|x86
32 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|ARM.ActiveCfg = Release|ARM
33 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|ARM.Build.0 = Release|ARM
34 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|ARM.Deploy.0 = Release|ARM
35 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|ARM64.ActiveCfg = Release|ARM64
36 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|ARM64.Build.0 = Release|ARM64
37 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|ARM64.Deploy.0 = Release|ARM64
38 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|x64.ActiveCfg = Release|x64
39 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|x64.Build.0 = Release|x64
40 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|x64.Deploy.0 = Release|x64
41 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|x86.ActiveCfg = Release|x86
42 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|x86.Build.0 = Release|x86
43 | {1359BDFF-04FF-4A5D-B55B-33E447D9FC52}.Release|x86.Deploy.0 = Release|x86
44 | EndGlobalSection
45 | GlobalSection(SolutionProperties) = preSolution
46 | HideSolutionNode = FALSE
47 | EndGlobalSection
48 | GlobalSection(ExtensibilityGlobals) = postSolution
49 | SolutionGuid = {789A7E5E-DBBC-489E-AEF3-7C7A59DD8E9D}
50 | EndGlobalSection
51 | EndGlobal
52 |
--------------------------------------------------------------------------------
/GraphTutorial/HomePage.xaml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
13 |
14 |
15 |
16 |
17 | Microsoft Graph UWP Tutorial
18 | Please sign in to continue.
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/GraphTutorial/HomePage.xaml.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation.
2 | // Licensed under the MIT License.
3 |
4 | using Windows.UI.Xaml.Controls;
5 |
6 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
7 |
8 | namespace GraphTutorial
9 | {
10 | ///
11 | /// An empty page that can be used on its own or navigated to within a Frame.
12 | ///
13 | public sealed partial class HomePage : Page
14 | {
15 | //
16 | public HomePage()
17 | {
18 | this.InitializeComponent();
19 |
20 | if ((App.Current as App).IsAuthenticated)
21 | {
22 | HomePageMessage.Text = "Welcome! Please use the menu to the left to select a view.";
23 | }
24 | }
25 | //
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/GraphTutorial/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
16 |
17 |
18 |
22 |
23 |
24 |
28 |
29 |
30 |
31 |
35 |
36 |
37 |
38 |
39 |
43 |
44 |
45 |
46 |
47 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/GraphTutorial/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation.
2 | // Licensed under the MIT License.
3 |
4 | using CommunityToolkit.Authentication;
5 | using Microsoft.Identity.Client;
6 | using Windows.UI.Xaml;
7 | using Windows.UI.Xaml.Controls;
8 |
9 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
10 |
11 | namespace GraphTutorial
12 | {
13 | ///
14 | /// An empty page that can be used on its own or navigated to within a Frame.
15 | ///
16 | public sealed partial class MainPage : Page
17 | {
18 | //
19 | public MainPage()
20 | {
21 | this.InitializeComponent();
22 |
23 | // Load OAuth settings
24 | var oauthSettings = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView("OAuth");
25 | var appId = oauthSettings.GetString("AppId");
26 | var scopes = oauthSettings.GetString("Scopes");
27 |
28 | if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(scopes))
29 | {
30 | Notification.Show("Could not load OAuth Settings from resource file.");
31 | }
32 | else
33 | {
34 | // Configure MSAL provider
35 | var msalClient = PublicClientApplicationBuilder.Create(appId)
36 | .WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient")
37 | .Build();
38 | ProviderManager.Instance.GlobalProvider = new MsalProvider(msalClient, scopes.Split(' '));
39 |
40 | // Handle auth state change
41 | ProviderManager.Instance.ProviderStateChanged += ProviderUpdated;
42 |
43 | // Navigate to HomePage.xaml
44 | RootFrame.Navigate(typeof(HomePage));
45 | }
46 | }
47 | //
48 |
49 | //
50 | private void ProviderUpdated(object sender, ProviderStateChangedEventArgs e)
51 | {
52 | var globalProvider = ProviderManager.Instance.GlobalProvider;
53 | SetAuthState(globalProvider != null && globalProvider.State == ProviderState.SignedIn);
54 | RootFrame.Navigate(typeof(HomePage));
55 | }
56 | //
57 |
58 | //
59 | private void SetAuthState(bool isAuthenticated)
60 | {
61 | (Application.Current as App).IsAuthenticated = isAuthenticated;
62 |
63 | // Toggle controls that require auth
64 | Calendar.IsEnabled = isAuthenticated;
65 | NewEvent.IsEnabled = isAuthenticated;
66 | }
67 | //
68 |
69 | private void NavView_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
70 | {
71 | var invokedItem = args.InvokedItem as string;
72 |
73 | switch (invokedItem.ToLower())
74 | {
75 | case "new event":
76 | RootFrame.Navigate(typeof(NewEventPage));
77 | break;
78 | case "calendar":
79 | RootFrame.Navigate(typeof(CalendarPage));
80 | break;
81 | case "home":
82 | default:
83 | RootFrame.Navigate(typeof(HomePage));
84 | break;
85 | }
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/GraphTutorial/NewEventPage.xaml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
13 |
14 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
32 |
36 |
40 |
45 |
46 |
53 |
57 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/GraphTutorial/NewEventPage.xaml.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation.
2 | // Licensed under the MIT License.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.ComponentModel;
7 | using System.Linq;
8 | using System.Runtime.CompilerServices;
9 | using CommunityToolkit.Authentication;
10 | using CommunityToolkit.Graph.Extensions;
11 | using Microsoft.Graph;
12 | using Microsoft.Graph.Extensions;
13 | using Microsoft.Toolkit.Uwp.UI.Controls;
14 | using Windows.UI.Xaml;
15 | using Windows.UI.Xaml.Controls;
16 | using Windows.UI.Xaml.Navigation;
17 |
18 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
19 |
20 | namespace GraphTutorial
21 | {
22 | ///
23 | /// An empty page that can be used on its own or navigated to within a Frame.
24 | ///
25 | public sealed partial class NewEventPage : Page, INotifyPropertyChanged
26 | {
27 | //
28 | public event PropertyChangedEventHandler PropertyChanged;
29 |
30 | private void OnPropertyChanged([CallerMemberName] string propertyName = "")
31 | {
32 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
33 | // Reevaluate if required fields are present and dates are valid
34 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsValid"));
35 | }
36 | //
37 |
38 | //
39 | private TimeZoneInfo _userTimeZone = null;
40 |
41 | // Value of the Subject text box
42 | private string _subject = "";
43 | public string Subject
44 | {
45 | get { return _subject; }
46 | set
47 | {
48 | _subject = value;
49 | OnPropertyChanged();
50 | }
51 | }
52 |
53 | // Value of the Start date picker
54 | private DateTimeOffset _startDate = DateTimeOffset.Now;
55 | public DateTimeOffset StartDate
56 | {
57 | get { return _startDate; }
58 | set
59 | {
60 | _startDate = value;
61 | OnPropertyChanged();
62 | }
63 | }
64 |
65 | // Value of the Start time picker
66 | private TimeSpan _startTime = TimeSpan.Zero;
67 | public TimeSpan StartTime
68 | {
69 | get { return _startTime; }
70 | set
71 | {
72 | _startTime = value;
73 | OnPropertyChanged();
74 | }
75 | }
76 |
77 | // Value of the End date picker
78 | private DateTimeOffset _endDate = DateTimeOffset.Now;
79 | public DateTimeOffset EndDate
80 | {
81 | get { return _endDate; }
82 | set
83 | {
84 | _endDate = value;
85 | OnPropertyChanged();
86 | }
87 | }
88 |
89 | // Value of the End time picker
90 | private TimeSpan _endTime = TimeSpan.Zero;
91 | public TimeSpan EndTime
92 | {
93 | get { return _endTime; }
94 | set
95 | {
96 | _endTime = value;
97 | OnPropertyChanged();
98 | }
99 | }
100 |
101 | // Value of the Body text box
102 | private string _body = "";
103 | public string Body
104 | {
105 | get { return _body; }
106 | set
107 | {
108 | _body = value;
109 | OnPropertyChanged();
110 | }
111 | }
112 |
113 | // Combine the date from date picker with time from time picker
114 | private DateTimeOffset CombineDateAndTime(DateTimeOffset date, TimeSpan time)
115 | {
116 | // Use the year, month, and day from the supplied DateTimeOffset
117 | // to create a new DateTime at midnight
118 | var dt = new DateTime(date.Year, date.Month, date.Day);
119 |
120 | // Add the TimeSpan, and use the user's timezone offset
121 | return new DateTimeOffset(dt + time, _userTimeZone.BaseUtcOffset);
122 | }
123 |
124 | // Combined value of Start date and time pickers
125 | public DateTimeOffset Start
126 | {
127 | get
128 | {
129 | return CombineDateAndTime(StartDate, StartTime);
130 | }
131 | }
132 |
133 | // Combined value of End date and time pickers
134 | public DateTimeOffset End
135 | {
136 | get
137 | {
138 | return CombineDateAndTime(EndDate, EndTime);
139 | }
140 | }
141 |
142 | public bool IsValid
143 | {
144 | get
145 | {
146 | // Subject is required, Start must be before
147 | // End
148 | return !string.IsNullOrWhiteSpace(Subject) &&
149 | DateTimeOffset.Compare(Start, End) < 0;
150 | }
151 | }
152 | //
153 |
154 | public NewEventPage()
155 | {
156 | InitializeComponent();
157 | DataContext = this;
158 | }
159 |
160 | //
161 | protected override async void OnNavigatedTo(NavigationEventArgs e)
162 | {
163 | // Get the Graph client from the provider
164 | var graphClient = ProviderManager.Instance.GlobalProvider.GetClient();
165 |
166 | try
167 | {
168 | // Get the user's mailbox settings to determine
169 | // their time zone
170 | var user = await graphClient.Me.Request()
171 | .Select(u => new { u.MailboxSettings })
172 | .GetAsync();
173 |
174 | _userTimeZone = TimeZoneInfo.FindSystemTimeZoneById(user.MailboxSettings.TimeZone);
175 | }
176 | catch (ServiceException graphException)
177 | {
178 | ShowNotification($"Exception getting user's mailbox settings from Graph, defaulting to local time zone: {graphException.Message}");
179 | _userTimeZone = TimeZoneInfo.Local;
180 | }
181 | catch (Exception ex)
182 | {
183 | ShowNotification($"Exception loading time zone from system: {ex.Message}");
184 | }
185 | }
186 |
187 | private void ShowNotification(string message)
188 | {
189 | // Get the main page that contains the InAppNotification
190 | var mainPage = (Window.Current.Content as Frame).Content as MainPage;
191 |
192 | // Get the notification control
193 | var notification = mainPage.FindName("Notification") as InAppNotification;
194 |
195 | notification.Show(message);
196 | }
197 | //
198 |
199 | //
200 | private async void CreateEvent(object sender, RoutedEventArgs e)
201 | {
202 | CreateProgress.IsActive = true;
203 | CreateProgress.Visibility = Visibility.Visible;
204 |
205 | // Get the Graph client from the provider
206 | var graphClient = ProviderManager.Instance.GlobalProvider.GetClient();
207 |
208 | // Initialize a new Event object with the required fields
209 | var newEvent = new Event
210 | {
211 | Subject = Subject,
212 | Start = Start.ToDateTimeTimeZone(_userTimeZone),
213 | End = End.ToDateTimeTimeZone(_userTimeZone)
214 | };
215 |
216 | // If there's a body, add it
217 | if (!string.IsNullOrEmpty(Body))
218 | {
219 | newEvent.Body = new ItemBody
220 | {
221 | Content = Body,
222 | ContentType = BodyType.Text
223 | };
224 | }
225 |
226 | // Add any attendees
227 | var peopleList = AttendeePicker.Items.ToList();
228 | var attendeeList = new List();
229 |
230 | foreach (object entry in peopleList)
231 | {
232 | // People Picker can contain Microsoft.Graph.Person objects
233 | // or text entries (for email addresses not found in the user's people list)
234 | if (entry is Person)
235 | {
236 | var person = entry as Person;
237 |
238 | attendeeList.Add(new Attendee
239 | {
240 | Type = AttendeeType.Required,
241 | EmailAddress = new EmailAddress
242 | {
243 | Address = person.ScoredEmailAddresses.First().Address
244 | }
245 | });
246 | }
247 | else if (entry is ITokenStringContainer)
248 | {
249 | var container = entry as ITokenStringContainer;
250 |
251 | // Treat any unrecognized text as a list of email addresses
252 | var emails = container.Text
253 | .Split(new[] { ';', ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
254 |
255 | foreach (var email in emails)
256 | {
257 | try
258 | {
259 | // Validate the email address
260 | var addr = new System.Net.Mail.MailAddress(email);
261 | if (addr.Address == email)
262 | {
263 | attendeeList.Add(new Attendee
264 | {
265 | Type = AttendeeType.Required,
266 | EmailAddress = new EmailAddress
267 | {
268 | Address = email
269 | }
270 | });
271 | }
272 | }
273 | catch { /* Invalid, skip */ }
274 | }
275 | }
276 | }
277 |
278 | if (attendeeList.Count > 0)
279 | {
280 | newEvent.Attendees = attendeeList;
281 | }
282 |
283 | try
284 | {
285 | await graphClient.Me.Events.Request().AddAsync(newEvent);
286 | }
287 | catch (ServiceException graphException)
288 | {
289 | ShowNotification($"Exception creating new event: ${graphException.Message}");
290 | }
291 |
292 | CreateProgress.IsActive = false;
293 | CreateProgress.Visibility = Visibility.Collapsed;
294 |
295 | ShowNotification("Event created");
296 | }
297 | //
298 | }
299 | }
300 |
--------------------------------------------------------------------------------
/GraphTutorial/OAuth.resw.example:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | YOUR_APP_ID_HERE
122 |
123 |
124 | User.Read User.ReadBasic.All People.Read MailboxSettings.Read Calendars.ReadWrite
125 |
126 |
--------------------------------------------------------------------------------
/GraphTutorial/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 |
16 |
17 | GraphTutorial
18 | contoso
19 | Assets\StoreLogo.png
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/GraphTutorial/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("GraphTutorial")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("GraphTutorial")]
13 | [assembly: AssemblyCopyright("Copyright © 2022")]
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)]
--------------------------------------------------------------------------------
/GraphTutorial/Properties/Default.rd.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Microsoft Graph
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | page_type: sample
3 | description: This sample demonstrates how to use the Microsoft Graph .NET SDK to access data in Office 365 from UWP apps.
4 | products:
5 | - ms-graph
6 | - office-exchange-online
7 | languages:
8 | - csharp
9 | - dotnet
10 | ---
11 |
12 | # Microsoft Graph sample UWP app
13 |
14 | [](https://github.com/microsoftgraph/msgraph-training-uwp/actions/workflows/msbuild.yml) 
15 |
16 | This sample demonstrates how to use the Microsoft Graph .NET SDK to access data in Office 365 from UWP apps.
17 |
18 | ## Prerequisites
19 |
20 | To run the completed project in this folder, you need the following:
21 |
22 | - [Visual Studio](https://visualstudio.microsoft.com/vs/) installed on your development machine. If you do not have Visual Studio, visit the previous link for download options. (**Note:** This tutorial was written with Visual Studio 2022 version 17.3.5. The steps in this guide may work with other versions, but that has not been tested.)
23 | - Either a personal Microsoft account with a mailbox on Outlook.com, or a Microsoft work or school account.
24 |
25 | If you don't have a Microsoft account, there are a couple of options to get a free account:
26 |
27 | - You can [sign up for a new personal Microsoft account](https://signup.live.com/signup?wa=wsignin1.0&rpsnv=12&ct=1454618383&rver=6.4.6456.0&wp=MBI_SSL_SHARED&wreply=https://mail.live.com/default.aspx&id=64855&cbcxt=mai&bk=1454618383&uiflavor=web&uaid=b213a65b4fdc484382b6622b3ecaa547&mkt=E-US&lc=1033&lic=1).
28 | - You can [sign up for the Microsoft 365 Developer Program](https://developer.microsoft.com/microsoft-365/dev-program) to get a free Microsoft 365 subscription.
29 |
30 | ## Register a native application with the Azure Active Directory admin center
31 |
32 | 1. Open a browser and navigate to the [Azure Active Directory admin center](https://aad.portal.azure.com) and login using a **personal account** (aka: Microsoft Account) or **Work or School Account**.
33 |
34 | 1. Select **Azure Active Directory** in the left-hand navigation, then select **App registrations** under **Manage**.
35 |
36 | 1. Select **New registration**. On the **Register an application** page, set the values as follows.
37 |
38 | - Set **Name** to `UWP Graph Sample`.
39 | - Set **Supported account types** to **Accounts in any organizational directory and personal Microsoft accounts**.
40 | - Under **Redirect URI**, change the dropdown to **Public client (mobile & desktop)**, and set the value to `https://login.microsoftonline.com/common/oauth2/nativeclient`.
41 |
42 | 1. Choose **Register**. On the **UWP Graph Tutorial** page, copy the value of the **Application (client) ID** and save it, you will need it in the next step.
43 |
44 | ## Configure the sample
45 |
46 | 1. Rename the OAuth.resw.example file to OAuth.resw.
47 | 1. Open `graph-tutorial.sln` in Visual Studio.
48 | 1. Edit the `OAuth.resw` file in visual studio. Replace `YOUR_APP_ID_HERE` with the **Application Id** you got from the App Registration Portal.
49 | 1. In Solution Explorer, right-click the **graph-tutorial** solution and choose **Restore NuGet Packages**.
50 |
51 | ## Run the sample
52 |
53 | In Visual Studio, press **F5** or choose **Debug > Start Debugging**.
54 |
55 | ## Code of conduct
56 |
57 | 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.
58 |
59 | ## Disclaimer
60 |
61 | **THIS CODE IS PROVIDED _AS IS_ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
62 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Security
4 |
5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
6 |
7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
8 |
9 | ## Reporting Security Issues
10 |
11 | **Please do not report security vulnerabilities through public GitHub issues.**
12 |
13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
14 |
15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
16 |
17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
18 |
19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
20 |
21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
22 | * Full paths of source file(s) related to the manifestation of the issue
23 | * The location of the affected source code (tag/branch/commit or direct URL)
24 | * Any special configuration required to reproduce the issue
25 | * Step-by-step instructions to reproduce the issue
26 | * Proof-of-concept or exploit code (if possible)
27 | * Impact of the issue, including how an attacker might exploit the issue
28 |
29 | This information will help us triage your report more quickly.
30 |
31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
32 |
33 | ## Preferred Languages
34 |
35 | We prefer all communications to be in English.
36 |
37 | ## Policy
38 |
39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
40 |
41 |
42 |
--------------------------------------------------------------------------------