Method "StartUpload" does not exist

I am trying to upload a large file (3 GB) from code, I have shrepoint server on a network without internet. I follwowed this toturial, I dowloaded from NuGet the package "Microsoft.SharePointOnline.CSOM" and tried this piece of code:

public Microsoft.SharePoint.Client.File UploadFileSlicePerSlice(ClientContext ctx, string libraryName, string fileName, int fileChunkSizeInMB = 3)
    {
        // Each sliced upload requires a unique ID.
        Guid uploadId = Guid.NewGuid();

        // Get the name of the file.
        string uniqueFileName = Path.GetFileName(fileName);

        // Ensure that target library exists, and create it if it is missing.
        if (!LibraryExists(ctx, ctx.Web, libraryName))
        {
            CreateLibrary(ctx, ctx.Web, libraryName);
        }
        // Get the folder to upload into. 
        List docs = ctx.Web.Lists.GetByTitle(libraryName);
        ctx.Load(docs, l => l.RootFolder);
        // Get the information about the folder that will hold the file.
        ctx.Load(docs.RootFolder, f => f.ServerRelativeUrl);
        ctx.ExecuteQuery();

        // File object.
        Microsoft.SharePoint.Client.File uploadFile;

        // Calculate block size in bytes.
        int blockSize = fileChunkSizeInMB * 1024 * 1024;

        // Get the information about the folder that will hold the file.
        ctx.Load(docs.RootFolder, f => f.ServerRelativeUrl);
        ctx.ExecuteQuery();


        // Get the size of the file.
        long fileSize = new FileInfo(fileName).Length;

        if (fileSize <= blockSize)
        {
            // Use regular approach.
            using (FileStream fs = new FileStream(fileName, FileMode.Open))
            {
                FileCreationInformation fileInfo = new FileCreationInformation();
                fileInfo.ContentStream = fs;
                fileInfo.Url = uniqueFileName;
                fileInfo.Overwrite = true;
                uploadFile = docs.RootFolder.Files.Add(fileInfo);
                ctx.Load(uploadFile);
                ctx.ExecuteQuery();
                // Return the file object for the uploaded file.
                return uploadFile;
            }
        }
        else
        {
            // Use large file upload approach.
            ClientResult<long> bytesUploaded = null;

            FileStream fs = null;
            try
            {
                fs = System.IO.File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                using (BinaryReader br = new BinaryReader(fs))
                {
                    byte[] buffer = new byte[blockSize];
                    Byte[] lastBuffer = null;
                    long fileoffset = 0;
                    long totalBytesRead = 0;
                    int bytesRead;
                    bool first = true;
                    bool last = false;

                    // Read data from file system in blocks. 
                    while ((bytesRead = br.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        totalBytesRead = totalBytesRead + bytesRead;

                        // You've reached the end of the file.
                        if (totalBytesRead == fileSize)
                        {
                            last = true;
                            // Copy to a new buffer that has the correct size.
                            lastBuffer = new byte[bytesRead];
                            Array.Copy(buffer, 0, lastBuffer, 0, bytesRead);
                        }

                        if (first)
                        {
                            using (MemoryStream contentStream = new MemoryStream())
                            {
                                // Add an empty file.
                                FileCreationInformation fileInfo = new FileCreationInformation();
                                fileInfo.ContentStream = contentStream;
                                fileInfo.Url = uniqueFileName;
                                fileInfo.Overwrite = true;
                                uploadFile = docs.RootFolder.Files.Add(fileInfo);

                                // Start upload by uploading the first slice. 
                                using (MemoryStream s = new MemoryStream(buffer))
                                {
                                    // Call the start upload method on the first slice.
                                    bytesUploaded = uploadFile.StartUpload(uploadId, s);
                                    ctx.ExecuteQuery();//<------here exception
                                    // fileoffset is the pointer where the next slice will be added.
                                    fileoffset = bytesUploaded.Value;
                                }

                                // You can only start the upload once.
                                first = false;
                            }
                        }
                        else
                        {
                            // Get a reference to your file.
                            uploadFile = ctx.Web.GetFileByServerRelativeUrl(docs.RootFolder.ServerRelativeUrl + System.IO.Path.AltDirectorySeparatorChar + uniqueFileName);

                            if (last)
                            {
                                // Is this the last slice of data?
                                using (MemoryStream s = new MemoryStream(lastBuffer))
                                {
                                    // End sliced upload by calling FinishUpload.
                                    uploadFile = uploadFile.FinishUpload(uploadId, fileoffset, s);
                                    ctx.ExecuteQuery();

                                    // Return the file object for the uploaded file.
                                    return uploadFile;
                                }
                            }
                            else
                            {
                                using (MemoryStream s = new MemoryStream(buffer))
                                {
                                    // Continue sliced upload.
                                    bytesUploaded = uploadFile.ContinueUpload(uploadId, fileoffset, s);
                                    ctx.ExecuteQuery();
                                    // Update fileoffset for the next slice.
                                    fileoffset = bytesUploaded.Value;
                                }
                            }
                        }

                    } // while ((bytesRead = br.Read(buffer, 0, buffer.Length)) > 0)
                }
            }
            finally
            {
                if (fs != null)
                {
                    fs.Dispose();
                }
            }
        }

        return null;
    }

But I'm getting runtime exception : ServerExction with the message: Method "StartUpload" does not exist at line "ctx.ExecuteQuery();" (I marked the line in the give code)

1 answer

  • answered 2019-06-25 01:21 LZ_MSFT

    Install the SharePoint Online CSOM library using the command below.

    Install-Package Microsoft.SharePointOnline.CSOM -Version 16.1.8924.1200
    

    Then use the code below to upload the large file.

    int blockSize = 8000000; // 8 MB
    string fileName = "C:\\temp\\6GBTest.odt", uniqueFileName = String.Empty;
    long fileSize;
    Microsoft.SharePoint.Client.File uploadFile = null;
    Guid uploadId = Guid.NewGuid();
    
    using (ClientContext ctx = new ClientContext("siteUrl"))
    {
        ctx.Credentials = new SharePointOnlineCredentials("user@tenant.onmicrosoft.com", GetSecurePassword());
        List docs = ctx.Web.Lists.GetByTitle("Documents");
        ctx.Load(docs.RootFolder, p => p.ServerRelativeUrl);
    
        // Use large file upload approach
        ClientResult<long> bytesUploaded = null;
    
        FileStream fs = null;
        try
        {
            fs = System.IO.File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
    
            fileSize = fs.Length;
            uniqueFileName = System.IO.Path.GetFileName(fs.Name);
    
            using (BinaryReader br = new BinaryReader(fs))
            {
                byte[] buffer = new byte[blockSize];
                byte[] lastBuffer = null;
                long fileoffset = 0;
                long totalBytesRead = 0;
                int bytesRead;
                bool first = true;
                bool last = false;
    
                // Read data from filesystem in blocks
                while ((bytesRead = br.Read(buffer, 0, buffer.Length)) > 0)
                {
                    totalBytesRead = totalBytesRead + bytesRead;
    
                    // We've reached the end of the file
                    if (totalBytesRead <= fileSize)
                    {
                        last = true;
                        // Copy to a new buffer that has the correct size
                        lastBuffer = new byte[bytesRead];
                        Array.Copy(buffer, 0, lastBuffer, 0, bytesRead);
                    }
    
                    if (first)
                    {
                        using (MemoryStream contentStream = new MemoryStream())
                        {
                            // Add an empty file.
                            FileCreationInformation fileInfo = new FileCreationInformation();
                            fileInfo.ContentStream = contentStream;
                            fileInfo.Url = uniqueFileName;
                            fileInfo.Overwrite = true;
                            uploadFile = docs.RootFolder.Files.Add(fileInfo);
    
                            // Start upload by uploading the first slice.
                            using (MemoryStream s = new MemoryStream(buffer))
                            {
                                // Call the start upload method on the first slice
                                bytesUploaded = uploadFile.StartUpload(uploadId, s);
                                ctx.ExecuteQuery();
                                // fileoffset is the pointer where the next slice will be added
                                fileoffset = bytesUploaded.Value;
                            }
    
                            // we can only start the upload once
                            first = false;
                        }
                    }
                    else
                    {
                        // Get a reference to our file
                        uploadFile = ctx.Web.GetFileByServerRelativeUrl(docs.RootFolder.ServerRelativeUrl + System.IO.Path.AltDirectorySeparatorChar + uniqueFileName);
    
                        if (last)
                        {
                            // Is this the last slice of data?
                            using (MemoryStream s = new MemoryStream(lastBuffer))
                            {
                                // End sliced upload by calling FinishUpload
                                uploadFile = uploadFile.FinishUpload(uploadId, fileoffset, s);
                                ctx.ExecuteQuery();
    
                                // return the file object for the uploaded file
                                return uploadFile;
                            }
                        }
                        else
                        {
                            using (MemoryStream s = new MemoryStream(buffer))
                            {
                                // Continue sliced upload
                                bytesUploaded = uploadFile.ContinueUpload(uploadId, fileoffset, s);
                                ctx.ExecuteQuery();
                                // update fileoffset for the next slice
                                fileoffset = bytesUploaded.Value;
                            }
                        }
                    }
    
                }
            }
        }
        finally
        {
            if (fs != null)
            {
                fs.Dispose();
            }
        }
    }
    

    Or download the example code from GitHub.

    Large file upload with CSOM