{"id":2259,"date":"2018-11-29T11:00:33","date_gmt":"2018-11-29T11:00:33","guid":{"rendered":"https:\/\/developer.microsoft.com\/en-us\/office\/blogs\/?p=2259"},"modified":"2018-11-29T11:00:33","modified_gmt":"2018-11-29T11:00:33","slug":"30daysmsgraph-day-29-use-case-upload-files-to-onedrive","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/30daysmsgraph-day-29-use-case-upload-files-to-onedrive\/","title":{"rendered":"30DaysMSGraph \u2013 Day 29 \u2013 Use case: Upload files to OneDrive"},"content":{"rendered":"<p><a href=\"https:\/\/aka.ms\/30DaysMSGraph\">List of all posts in the #30DaysMSGraph series<\/a><\/p>\n<p>-Today&#8217;s post written by <a href=\"https:\/\/twitter.com\/fizzlenik\">Jeremy Kelley<\/a><\/p>\n<p>In <a href=\"https:\/\/developer.microsoft.com\/en-us\/graph\/blogs\/30daysmsgraph-day-28-use-case-webhooks\/\">Day 28<\/a> we created a webhook notification for Microsoft Graph events.\u00a0 Today we will interact with files stored in OneDrive.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-2262\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2018\/11\/30DaysMSGraph_Day29_Source-1024x682.jpg\" alt=\"\" width=\"800\" height=\"533\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2018\/11\/30DaysMSGraph_Day29_Source-1024x682.jpg 1024w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2018\/11\/30DaysMSGraph_Day29_Source-300x200.jpg 300w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2018\/11\/30DaysMSGraph_Day29_Source-768x512.jpg 768w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2018\/11\/30DaysMSGraph_Day29_Source-1536x1024.jpg 1536w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2018\/11\/30DaysMSGraph_Day29_Source.jpg 2000w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<h3>Prerequisites<\/h3>\n<p>For today\u2019s sample we\u2019ll be using <a href=\"https:\/\/visualstudio.microsoft.com\/downloads\/\">Visual Studio Community edition<\/a>.\u00a0 We recommended that you have finished the basic console application sample from Day 15.<\/p>\n<p>To follow along with the\u00a0sample, you can either download the provided sample code for Day 29 [Add link to GitHub] or follow these setup instructions:<\/p>\n<ol>\n<li>Install Visual Studio Community Edition<\/li>\n<li>Create a new blank Universal Windows application<\/li>\n<li>Add the following NuGet packages\n<ul>\n<li>Microsoft.Graph<\/li>\n<li>Microsoft.Identity.Client<\/li>\n<\/ul>\n<\/li>\n<li>Add the following using declarations to your\u00a0MainPage\u00a0class:<\/li>\n<\/ol>\n<pre class=\"toolbar-overlay:false toolbar-hide:false lang:default decode:true\">using&amp;nbsp;Microsoft.Identity.Client;&amp;nbsp;\nusing&amp;nbsp;System.Threading.Tasks;&amp;nbsp;\nusing&amp;nbsp;System.Net.Http.Headers;&amp;nbsp;\nusing&amp;nbsp;Windows.Storage;&amp;nbsp;\nusing&amp;nbsp;Windows.Storage.Pickers;<\/pre>\n<ol start=\"5\">\n<li>In\u00a0MainPage.xaml.cs\u00a0add the following code\u00a0below the\u00a0MainPage\u00a0constructor:<\/li>\n<\/ol>\n<pre class=\"h-align:1 toolbar-overlay:false toolbar-hide:false toolbar-delay:false show-plain:1 lang:default decode:true\">\u00a0\u00a0\u00a0\u00a0private const string\u00a0AADClientId\u00a0= \"YOURAPPIDHERE\";\u00a0\n\u00a0\u00a0\u00a0\u00a0private const string\u00a0GraphAPIEndpointPrefix\u00a0= \"https:\/\/graph.microsoft.com\/v1.0\/\";\u00a0\n\u00a0\u00a0\u00a0\u00a0private\u00a0string[]\u00a0AADScopes\u00a0= new string[] { \"files.readwrite.all\" };\u00a0\n\u00a0\u00a0\u00a0\u00a0private\u00a0PublicClientApplication\u00a0AADAppContext\u00a0= null;\u00a0\n\u00a0\u00a0\u00a0\u00a0private\u00a0GraphServiceClient\u00a0graphClient\u00a0= null;\u00a0\n\u00a0\u00a0\u00a0\u00a0private\u00a0AuthenticationResult\u00a0userCredentials;\u00a0\n\u00a0\u00a0\u00a0\u00a0public\u00a0AuthenticationResult\u00a0UserCredentials\u00a0\n\u00a0\u00a0\u00a0\u00a0{\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 get\u00a0{ return\u00a0userCredentials; }\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 set\u00a0{\u00a0userCredentials\u00a0= value; }\u00a0\n\u00a0\u00a0\u00a0\u00a0}\u00a0\n\n\u00a0\u00a0\u00a0\u00a0public void\u00a0InitializeGraph()\u00a0\n\u00a0\u00a0\u00a0\u00a0{\u00a0\n\u00a0\u00a0\u00a0\u00a0  \u00a0 if (userCredentials\u00a0!= null)\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0graphClient\u00a0= new\u00a0GraphServiceClient(\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GraphAPIEndpointPrefix,\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 new\u00a0DelegateAuthenticationProvider(\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 async (requestMessage) =&amp;amp;gt;\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0requestMessage.Headers.Authorization\u00a0= new\u00a0AuthenticationHeaderValue(\"bearer\",\u00a0userCredentials.AccessToken);\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 );\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\u00a0\n\u00a0\u00a0\u00a0 }\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\/\/\/ &amp;amp;lt;summary&amp;amp;gt;\u00a0\n\u00a0\u00a0\u00a0\u00a0\/\/\/ Log the user in to either Office\u00a0365 or OneDrive consumer\u00a0\n\u00a0\u00a0\u00a0\u00a0\/\/\/ &amp;amp;lt;\/summary&amp;amp;gt;\u00a0\n\u00a0\u00a0\u00a0\u00a0\/\/\/ &amp;amp;lt;returns&amp;amp;gt;A task to await on&amp;amp;lt;\/returns&amp;amp;gt;\u00a0\n\u00a0\u00a0\u00a0\u00a0public async Task&amp;amp;lt;string&amp;amp;gt;\u00a0SignInUser()\u00a0\n\u00a0\u00a0\u00a0\u00a0{\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 string status = \"Unknown\";\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Instantiate the app with AAD\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0AADAppContext\u00a0= new\u00a0PublicClientApplication(AADClientId);\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0try\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0UserCredentials\u00a0= await\u00a0AADAppContext.AcquireTokenAsync(AADScopes);\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (UserCredentials\u00a0!= null)\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 status = \"Signed in as \" +\u00a0UserCredentials.Account.Username;\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0InitializeGraph();\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0catch (MsalServiceException\u00a0serviceEx)\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 status = $\"Could not sign in, error code: \" +\u00a0serviceEx.ErrorCode;\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0catch (Exception ex)\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 status = $\"Error Acquiring Token: {ex}\";\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return (status);\n\u00a0\u00a0\u00a0 }<\/pre>\n<ol start=\"6\">\n<li>Replace YOURAPPIDHERE with the id of your application created in the basic console application\u00a0example.<\/li>\n<\/ol>\n<h3>Working with files<\/h3>\n<p>Files are the backbone of many tasks you might want to do with OneDrive or SharePoint using the Microsoft Graph APIs.\u00a0 When working with files the first thing to start with is always a Drive.\u00a0 Drives can be a user\u2019s OneDrive or a Document Library in a SharePoint site.<\/p>\n<p>Accessing the files in OneDrive is as easy as accessing the \/me\/drive endpoint.\u00a0 From that starting point you can enumerate the children, download content, upload new files, and even do things like convert content from one format to another.<\/p>\n<p>In SharePoint you first need to address the site that the file is in.\u00a0 You can do this in one of several ways.<\/p>\n<p>List all drives in a site by Id:<\/p>\n<pre class=\"h-align:1 toolbar-overlay:false lang:default decode:true \">GET \/sites\/{id}\/drives<\/pre>\n<p>Get\u00a0the default drive in a site by Id:<\/p>\n<pre class=\"toolbar-overlay:false toolbar-hide:false lang:default decode:true \">GET \/sites\/{id}\/drive<\/pre>\n<p>You can also access sites by path\u00a0if you don\u2019t happen to know the Id.<\/p>\n<p>List all drives in a site by path:<\/p>\n<pre class=\"toolbar-overlay:false toolbar-hide:false lang:default decode:true \">GET\u00a0\/sites\/TENANTHOSTURL:\/SITEPATH:\/drives<\/pre>\n<p>Get the default drive in a site by path:<\/p>\n<pre class=\"toolbar-overlay:false toolbar-hide:false lang:default decode:true \">GET \/sites\/TENANTHOSTURL:\/SITEPATH:\/drives<\/pre>\n<p>In this post and the associated code sample we\u2019re going to look at how to upload files\u00a0to either the currently logged in user\u2019s OneDrive for Business or the default document library in the root site collection of the signed in user\u2019s tenant.<\/p>\n<p>You can easily adapt this code to upload to other locations as you see fit.<\/p>\n<h3>Add\u00a0required\u00a0scopes<\/h3>\n<p>When working with files you can ask for one of several permissions.\u00a0 To access only the user\u2019s\u00a0OneDrive\u00a0ask for\u00a0<strong>Files.Read<\/strong>\u00a0or\u00a0<strong>Files.ReadWrite<\/strong>.\u00a0 To access or create files anywhere the user has access use\u00a0<strong>Files.Read.All<\/strong>\u00a0or\u00a0<strong>Files.ReadWrite.All<\/strong>.<\/p>\n<p>To enable our code to upload files to either OneDrive or SharePoint we\u2019ll use\u00a0<strong>Files.ReadWrite.All<\/strong>.<\/p>\n<p>Since you didn\u2019t assign the\u00a0<strong>Files.ReadWrite.All<\/strong>\u00a0permission in a previous day ensure that you assign that now to your Azure AD application.\u202f Navigate to the\u00a0<a href=\"http:\/\/aka.ms\/appregistrationspreview\">Preview App Registrations<\/a>\u00a0experience in the Azure AD portal and assign the\u00a0delegated\u00a0permission for\u00a0<strong>Files.ReadWrite.All<\/strong>\u00a0under Microsoft Graph API.<\/p>\n<h3>Upload a small file<\/h3>\n<p>For files less than 4MB you can use a PUT\u00a0to upload the file\u00a0directly to the location you want.\u00a0 To implement the upload method,\u00a0add the code below to your\u00a0MainPage\u00a0class.<\/p>\n<pre class=\"toolbar-overlay:false toolbar-hide:false lang:default decode:true\">&amp;nbsp;&amp;nbsp;&amp;nbsp; \/\/\/ &lt;summary&gt;&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/\/\/ Take a file and upload it to the service&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/\/\/ &lt;\/summary&gt;&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/\/\/ &lt;param name=\"fileToUpload\"&gt;The file that we want to upload&lt;\/param&gt;&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/\/\/ &lt;param name=\"uploadToSharePoint\"&gt;Should we upload to SharePoint or&amp;nbsp;OneDrive?&lt;\/param&gt;&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public async Task&amp;nbsp;UploadSmallFile(StorageFile&amp;nbsp;fileToUpload, bool&amp;nbsp;uploadToSharePoint)&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Stream&amp;nbsp;fileStream&amp;nbsp;= (await&amp;nbsp;fileToUpload.OpenReadAsync()).AsStreamForRead();&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DriveItem&amp;nbsp;uploadedFile&amp;nbsp;= null;&amp;nbsp;\n\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; \/\/ Do we want OneDrive for Business\/Consumer or do we want a SharePoint Site?&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (uploadToSharePoint)&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uploadedFile&amp;nbsp;= await graphClient.Sites[\"root\"].Drive.Root.ItemWithPath(fileToUpload.Name).Content.Request().PutAsync&lt;DriveItem&gt;(fileStream);&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uploadedFile&amp;nbsp;= await&amp;nbsp;graphClient.Me.Drive.Root.ItemWithPath(fileToUpload.Name).Content.Request().PutAsync&lt;DriveItem&gt;(fileStream);&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp; }<\/pre>\n<h3>Upload a large file<\/h3>\n<p>To upload files larger than 4MB we need to use the\u00a0CreateUploadSession\u00a0pattern.\u00a0 In this pattern we instruct the service to begin a session that we will then upload\u00a0chunks of data to one at a time.\u00a0 To implement the large upload\u00a0pattern\u00a0add the following method to your class:<\/p>\n<pre class=\"toolbar-overlay:false toolbar-hide:false lang:default decode:true \">\u00a0\u00a0\u00a0 \/\/\/ &amp;lt;summary&amp;gt;\u00a0\n\u00a0\u00a0\u00a0\u00a0\/\/\/ Take a file greater than 4MB and upload it to the service\u00a0\n\u00a0\u00a0\u00a0\u00a0\/\/\/ &amp;lt;\/summary&amp;gt;\u00a0\n\u00a0\u00a0\u00a0\u00a0\/\/\/ &amp;lt;param name=\"fileToUpload\"&amp;gt;The file that we want to upload&amp;lt;\/param&amp;gt;\u00a0\n\u00a0\u00a0\u00a0\u00a0\/\/\/ &amp;lt;param name=\"uploadToSharePoint\"&amp;gt;Should we upload to SharePoint or\u00a0OneDrive?&amp;lt;\/param&amp;gt;\u00a0\n\u00a0\u00a0\u00a0\u00a0public async Task&amp;lt;DriveItem&amp;gt;\u00a0UploadLargeFile(StorageFile\u00a0fileToUpload, bool\u00a0uploadToSharePoint)\u00a0\n\u00a0\u00a0\u00a0\u00a0{\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Stream\u00a0fileStream\u00a0= (await\u00a0fileToUpload.OpenReadAsync()).AsStreamForRead();\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DriveItem\u00a0uploadedFile\u00a0= null;\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0UploadSession\u00a0uploadSession\u00a0= null;\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Do we want OneDrive for Business\/Consumer or do we want a SharePoint Site?\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (uploadToSharePoint)\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uploadSession\u00a0= await graphClient.Sites[\"root\"].Drive.Root.ItemWithPath(fileToUpload.Name).CreateUploadSession().Request().PostAsync();\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 else\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uploadSession\u00a0= await\u00a0graphClient.Me.Drive.Root.ItemWithPath(fileToUpload.Name).CreateUploadSession().Request().PostAsync();\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if(uploadSession\u00a0!= null)\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Chunk size must be divisible by 320KiB, our chunk size will be slightly more than 1MB\u00a0\n\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 int\u00a0maxSizeChunk\u00a0= (320 * 1024) * 4;\u00a0\n            ChunkedUploadProvider\u00a0uploadProvider\u00a0= new\u00a0ChunkedUploadProvider(uploadSession,\u00a0graphClient,\u00a0fileStream,\u00a0maxSizeChunk);\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 var\u00a0chunkRequests\u00a0=\u00a0uploadProvider.GetUploadChunkRequests();\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 var exceptions = new List&amp;lt;Exception&amp;gt;();\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 var\u00a0readBuffer\u00a0= new byte[maxSizeChunk];\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 foreach (var request in\u00a0chunkRequests)\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 var result = await\u00a0uploadProvider.GetChunkRequestResponseAsync(request,\u00a0readBuffer, exceptions);\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if(result.UploadSucceeded)\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uploadedFile\u00a0=\u00a0result.ItemResponse;\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return (uploadedFile);\u00a0\n\u00a0\u00a0\u00a0 }<\/pre>\n<h3>Add an interface<\/h3>\n<p>Now we need to add some interface elements to our project to allow us to pick files and upload them.<\/p>\n<p>In your\u00a0MainPage.xaml\u00a0file replace the default Grid element with the following markup:<\/p>\n<pre class=\"toolbar-overlay:false toolbar-hide:false lang:default decode:true\">&lt;RelativePanel&gt;&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;RelativePanel&amp;nbsp;RelativePanel.AlignHorizontalCenterWithPanel=\"True\"&amp;nbsp;RelativePanel.AlignVerticalCenterWithPanel=\"True\"&gt;&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;CheckBox&amp;nbsp;x:Name=\"uploadToSharePointCheckBox\" Margin=\"10,10,10,10\"&gt;Upload to SharePoint?&lt;\/CheckBox&gt;&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;Button&amp;nbsp;x:Name=\"uploadSmallFileButton\" Margin=\"10,10,10,10\" Click=\"uploadSmallFileButton_Click\"&amp;nbsp;RelativePanel.Below=\"uploadToSharePointCheckBox\"&amp;nbsp;RelativePanel.AlignHorizontalCenterWithPanel=\"True\"&gt;Upload small file&lt;\/Button&gt;&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;Button&amp;nbsp;x:Name=\"uploadLargeFileButton\" Margin=\"10,10,10,10\" Click=\"uploadLargeFileButton_Click\"&amp;nbsp;RelativePanel.Below=\"uploadSmallFileButton\"&amp;nbsp;RelativePanel.AlignHorizontalCenterWithPanel=\"True\"&gt;Upload large file&lt;\/Button&gt;&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;TextBlock&amp;nbsp;x:Name=\"statusTextBlock\" Margin=\"10,10,10,10\"&amp;nbsp;RelativePanel.Below=\"uploadLargeFileButton\"&amp;nbsp;RelativePanel.AlignHorizontalCenterWithPanel=\"True\" \/&gt;&amp;nbsp;\n&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;\/RelativePanel&gt;&amp;nbsp;\n&lt;\/RelativePanel&gt;\n<\/pre>\n<p>In your code behind (MainPage.xaml.cs) file add the following code to connect the buttons to call our upload methods:<\/p>\n<pre class=\"toolbar-overlay:false toolbar-hide:false lang:default decode:true \">\u00a0\u00a0\u00a0 private async Task&amp;lt;StorageFile&amp;gt;\u00a0PickFile()\u00a0\n\u00a0\u00a0\u00a0 {\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 var picker = new\u00a0FileOpenPicker();\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0picker.ViewMode\u00a0=\u00a0PickerViewMode.Thumbnail;\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0picker.SuggestedStartLocation\u00a0=\u00a0PickerLocationId.PicturesLibrary;\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0picker.FileTypeFilter.Add(\".jpg\");\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0picker.FileTypeFilter.Add(\".jpeg\");\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0picker.FileTypeFilter.Add(\".png\");\u00a0\n\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0StorageFile\u00a0pickedFile\u00a0= await\u00a0picker.PickSingleFileAsync();\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return (pickedFile);\u00a0\n\u00a0\u00a0\u00a0 }\u00a0\n\n\u00a0\u00a0\u00a0 private async Task\u00a0UploadFile(object\u00a0whichButton)\u00a0\n\u00a0\u00a0\u00a0 {\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (this.UserCredentials\u00a0== null)\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 await\u00a0SignInUser();\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0StorageFile\u00a0fileToUpload\u00a0= await\u00a0PickFile();\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DriveItem\u00a0uploadedFile\u00a0= null;\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (whichButton\u00a0==\u00a0this.uploadSmallFileButton)\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uploadedFile\u00a0= await\u00a0UploadSmallFile(fileToUpload);\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 else\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uploadedFile\u00a0= await\u00a0UploadLargeFile(fileToUpload);\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (uploadedFile\u00a0!= null)\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.statusTextBlock.Text\u00a0= \"Uploaded file: \" +\u00a0uploadedFile.Name;\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 else\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.statusTextBlock.Text\u00a0= \"Upload failed\";\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\u00a0\n\u00a0\u00a0\u00a0 }\u00a0\n\n\u00a0\u00a0\u00a0\u00a0private async void\u00a0uploadSmallFileButton_Click(object sender,\u00a0RoutedEventArgs\u00a0e)\u00a0\n\u00a0\u00a0\u00a0\u00a0{\u00a0\n\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0 await\u00a0UploadFile(sender);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a0}\u00a0\n\n\u00a0\u00a0\u00a0\u00a0private async void\u00a0uploadLargeFileButton_Click(object sender,\u00a0RoutedEventArgs\u00a0e)\u00a0\n\u00a0\u00a0\u00a0\u00a0{\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 await\u00a0UploadFile(sender);\u00a0\n\u00a0\u00a0\u00a0\u00a0}\n<\/pre>\n<h3>Beyond upload<\/h3>\n<p>Uploading files is just the beginning.\u00a0 When you upload files to SharePoint you can combine\u00a0file operations with metadata to fulfill scenarios tailored to your\u00a0needs.\u00a0 If you are working in large scale\u00a0scenarios\u00a0please check out our\u00a0<a href=\"https:\/\/aka.ms\/scanguidance\">best practices\u00a0for\u00a0discovering files and detecting changes at scale<\/a>.<\/p>\n<h2>Try It Out<\/h2>\n<p>Navigate to the <a href=\"https:\/\/github.com\/microsoftgraph\/30DaysMSGraph-TryItOut\">30DaysMSGraph-TryItOut<\/a>\u202frepo. Clone the repo and configure the project in the Day 29\u00a0sub-folder using steps from the README or this post.<\/p>\n<p>If you run into any issues while building or configuring the project, please create a new Issue on the repo.<\/p>\n<p>Join us tomorrow as we wrap up the 30 Days of Microsoft Graph series with community resources and next steps suggestions in <a href=\"https:\/\/developer.microsoft.com\/en-us\/graph\/blogs\/30daysmsgraph-day-30-community-resources-and-next-steps\/\">Day 30<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Day 28 we created a webhook notification for Microsoft Graph events.\u00a0 Today we will interact with files stored in OneDrive.<\/p>\n","protected":false},"author":73055,"featured_media":25159,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3],"tags":[84,35],"class_list":["post-2259","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microsoft-graph","tag-30daysmsgraph","tag-onedrive"],"acf":[],"blog_post_summary":"<p>In Day 28 we created a webhook notification for Microsoft Graph events.\u00a0 Today we will interact with files stored in OneDrive.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/2259","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/users\/73055"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/comments?post=2259"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/2259\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media\/25159"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media?parent=2259"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/categories?post=2259"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/tags?post=2259"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}