将大文件上载到Sharepoint 365

时间:2013-02-25 21:59:14

标签: sharepoint-api office365

我正在使用CSOM将文件上传到Sharepoint 365网站。

我使用“http://www.wictorwilen.se/Post/How-to-do-active-authentication-to-Office-365-and-SharePoint-Online.aspx”中的方法成功登录了基于声明的身份验证

但是在ClientContext上使用SaveBinaryDirect失败了,因为过早地将cookie附加到请求,因此使用了405.

使用CSOM上传文件的另一种方法与下面类似。但是使用SP 365,这会将文件大小限制为大约3兆。

 var newFileFromComputer = new FileCreationInformation
                {
                    Content = fileContents,
                    Url = Path.GetFileName(sourceUrl)
                };


 Microsoft.SharePoint.Client.File uploadedFile = customerFolder.Files.Add(newFileFromComputer);
                    context.Load(uploadedFile);
                    context.ExecuteQuery();

有没有办法使用CSOM,SP 365和文件大小说100兆?

2 个答案:

答案 0 :(得分:1)

好吧,我还没有办法用CSOM做到这一点,这确实令人愤怒。

SEvans在http://www.wictorwilen.se/Post/How-to-do-active-authentication-to-Office-365-and-SharePoint-Online.aspx的评论中发布了一个解决方案。

基本上只需执行http放置并附加基于声明的身份验证的cookie集合。 SEvans发布的解决方法在

之下

伟大的代码Wichtor。正如其他人所说,SaveBinaryDirect无法正常工作,因为FedAuth cookie永远不会附加到该方法生成的HTTP PUT请求。

这是我的解决方法 - 希望这有助于你们中的一些人:

// "url" is the full destination path (including filename, i.e. https://mysite.sharepoint.com/Documents/Test.txt) 

// "cookie" is the CookieContainer generated from Wichtor's code 
// "data" is the byte array containing the files contents (used a FileStream to load) 

System.Net.ServicePointManager.Expect100Continue = false; 
HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest; 
request.Method = "PUT"; 
request.Accept = "*/*"; 
request.ContentType = "multipart/form-data; charset=utf-8"; 
request.CookieContainer = cookie; request.AllowAutoRedirect = false; 
request.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)"; 
request.Headers.Add("Accept-Language", "en-us"); 
request.Headers.Add("Translate", "F"); request.Headers.Add("Cache-Control", "no-cache"); request.ContentLength = data.Length; 

using (Stream req = request.GetRequestStream()) 
{ req.Write(data, 0, data.Length); } 

HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
Stream res = response.GetResponseStream(); 
StreamReader rdr = new StreamReader(res); 
string rawResponse = rdr.ReadToEnd(); 
response.Close();
rdr.Close();

答案 1 :(得分:0)

实际上是试图在SharePoint Online中上载文件大小超过250MB的文件限制时,将发生以下异常:

  

收到的回复为-1,   Microsoft.SharePoint.Client.InvalidClientQueryException请求   消息太大。服务器不允许消息大于   262144000字节。

为避免此错误,我们引入了chunked file upload methods,该错误支持上传大于250 MB的文件。在提供的链接中,有一个示例演示了如何通过SharePoint CSOM API来使用它。

  

支持的版本:

     
      
  • SharePoint在线
  •   
  • SharePoint内部部署 2016 或更高版本
  •   

以下示例演示了如何在SharePoint REST API中利用分块文件上传方法:

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();
        }
    }
}

源代码:FileUploader.cs

用法

var userCredentials = GetCredentials(userName, password);
var sourcePath = @"C:\temp\jellyfish-25-mbps-hd-hevc.mkv"; //local file path
var targetFolderUrl = "/Shared Documents"; //library reltive url
FileUploader.ChunkedFileUpload(webUrl,
       userCredentials,
       sourcePath, 
       targetFolderUrl, 
       1024 * 1024 * 5, //5MB
       (offset, size) =>
       {
            Console.WriteLine("{0:P} completed", (offset / (float)size));
       });

参考

Always use File Chunking to Upload Files > 250 MB to SharePoint Online