Last active
October 4, 2019 16:49
-
-
Save vgrem/d313805b9b4401c9ccefff2c2782f866 to your computer and use it in GitHub Desktop.
SharePoint Online REST API chunked file upload
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net; | |
using Newtonsoft.Json.Linq; | |
namespace SharePoint.FileOperations | |
{ | |
class FileUploader | |
{ | |
public static void ChunkedFileUpload(string webUrl, ICredentials credentials, string sourcePath, string targetFolderUrl, int chunkSizeBytes, Action<long, long> chunkUploaded) | |
{ | |
using (var client = new WebClient()) | |
{ | |
client.BaseAddress = webUrl; | |
client.Credentials = credentials; | |
client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f"); | |
var formDigest = RequestFormDigest(webUrl, credentials); | |
client.Headers.Add("X-RequestDigest", formDigest); | |
//create an empty file first | |
var fileName = System.IO.Path.GetFileName(sourcePath); | |
var createFileRequestUrl = string.Format("/_api/web/getfolderbyserverrelativeurl('{0}')/files/add(url='{1}',overwrite=true)", targetFolderUrl, fileName); | |
client.UploadString(createFileRequestUrl, "POST"); | |
var targetUrl = System.IO.Path.Combine(targetFolderUrl, fileName); | |
var firstChunk = true; | |
var uploadId = Guid.NewGuid(); | |
var offset = 0L; | |
using (var inputStream = System.IO.File.OpenRead(sourcePath)) | |
{ | |
var buffer = new byte[chunkSizeBytes]; | |
int bytesRead; | |
while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0) | |
{ | |
if (firstChunk) | |
{ | |
var endpointUrl = string.Format("/_api/web/getfilebyserverrelativeurl('{0}')/startupload(uploadId=guid'{1}')", targetUrl, uploadId); | |
client.UploadData(endpointUrl, buffer); | |
firstChunk = false; | |
} | |
else if (inputStream.Position == inputStream.Length) | |
{ | |
var endpointUrl = string.Format("/_api/web/getfilebyserverrelativeurl('{0}')/finishupload(uploadId=guid'{1}',fileOffset={2})", targetUrl, uploadId, offset); | |
var finalBuffer = new byte[bytesRead]; | |
Array.Copy(buffer, finalBuffer, finalBuffer.Length); | |
client.UploadData(endpointUrl, finalBuffer); | |
} | |
else | |
{ | |
var endpointUrl = string.Format("/_api/web/getfilebyserverrelativeurl('{0}')/continueupload(uploadId=guid'{1}',fileOffset={2})", targetUrl, uploadId, offset); | |
client.UploadData(endpointUrl, buffer); | |
} | |
offset += bytesRead; | |
chunkUploaded(offset, inputStream.Length); | |
} | |
} | |
} | |
} | |
public static string RequestFormDigest(string webUrl, ICredentials credentials) | |
{ | |
using (var client = new WebClient()) | |
{ | |
client.BaseAddress = webUrl; | |
client.Credentials = credentials; | |
client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f"); | |
client.Headers.Add("Accept", "application/json; odata=verbose"); | |
var endpointUrl = "/_api/contextinfo"; | |
var content = client.UploadString(endpointUrl, "POST"); | |
var data = JObject.Parse(content); | |
return data["d"]["GetContextWebInformation"]["FormDigestValue"].ToString(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment