如何使用 CSOM 从/向 SharePoint 2013 下载/上传文件?

Posted

技术标签:

【中文标题】如何使用 CSOM 从/向 SharePoint 2013 下载/上传文件?【英文标题】:How to download/upload files from/to SharePoint 2013 using CSOM? 【发布时间】:2013-06-08 01:38:05 【问题描述】:

我正在开发一个 Win8(WinRT、C#、XAML)客户端应用程序 (CSOM),它需要从 SharePoint 2013 下载/上传文件。

如何进行下载/上传?

【问题讨论】:

【参考方案1】:

上传文件

使用File.SaveBinaryDirect Method 将文件上传到 SharePoint 网站(包括 SharePoint Online):

using (var clientContext = new ClientContext(url))

     using (var fs = new FileStream(fileName, FileMode.Open))
     
         var fi = new FileInfo(fileName);
         var list = clientContext.Web.Lists.GetByTitle(listTitle);
         clientContext.Load(list.RootFolder);
         clientContext.ExecuteQuery();
         var fileUrl = String.Format("0/1", list.RootFolder.ServerRelativeUrl, fi.Name);

         Microsoft.SharePoint.Client.File.SaveBinaryDirect(clientContext, fileUrl, fs, true);
     

下载文件

使用File.OpenBinaryDirect Method从 SharePoint 网站(包括 SharePoint Online)下载文件:

using (var clientContext = new ClientContext(url))


     var list = clientContext.Web.Lists.GetByTitle(listTitle);
     var listItem = list.GetItemById(listItemId);
     clientContext.Load(list);
     clientContext.Load(listItem, i => i.File);
     clientContext.ExecuteQuery();

     var fileRef = listItem.File.ServerRelativeUrl;
     var fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(clientContext, fileRef);
     var fileName = Path.Combine(filePath,(string)listItem.File.Name);
     using (var fileStream = System.IO.File.Create(fileName))
                       
          fileInfo.Stream.CopyTo(fileStream);
     

【讨论】:

Vadim,1. 我收到关于 ICredentials 和路径的错误。我需要做什么吗。 2. 您已经在 XML 文件中注释了 的位置。我是新手,请给我更多关于这方面的信息。我正在尝试将文件从 Sharepoint 站点下载到我的本地驱动器。 关于凭据,NetworkCredential 用于本地环境,SharePoint Online 中的 SharePointOnlineCredentials 我试过你的上传方法,得到“远程服务器返回错误:(401) Unauthorized” @Apollo,请参阅我之前关于使用哪些凭据的评论【参考方案2】:

此article 描述了访问 SharePoint 内容的各种选项。您可以在 REST 和 CSOM 之间进行选择。如果可能,我会尝试 CSOM。文件上传/下载具体在this文章中有很好的描述。

总体说明:

    //First construct client context, the object which will be responsible for
    //communication with SharePoint:
    var context = new ClientContext(@"http://site.absolute.url")

    //then get a hold of the list item you want to download, for example
    var list = context.Web.Lists.GetByTitle("Pipeline");
    var query = CamlQuery.CreateAllItemsQuery(10000);
    var result = list.GetItems(query);

    //note that data has not been loaded yet. In order to load the data
    //you need to tell SharePoint client what you want to download:

    context.Load(result, items=>items.Include(
        item => item["Title"],
        item => item["FileRef"]
    ));

    //now you get the data
    context.ExecuteQuery();

    //here you have list items, but not their content (files). To download file
    //you'll have to do something like this:

    var item = items.First();

    //get the URL of the file you want:
    var fileRef = item["FileRef"];

    //get the file contents:
    FileInformation fileInfo = File.OpenBinaryDirect(context, fileRef.ToString());

    using (var memory = new MemoryStream())
    
          byte[] buffer = new byte[1024 * 64];
          int nread = 0;
          while ((nread = fileInfo.Stream.Read(buffer, 0, buffer.Length)) > 0)
          
              memory.Write(buffer, 0, nread);
          
          memory.Seek(0, SeekOrigin.Begin);
          // ... here you have the contents of your file in memory, 
          // do whatever you want
    

避免直接使用流,先将其读入内存。网络绑定的流不一定支持流操作,更不用说性能了。因此,如果您正在从该流中读取图片或解析文档,您最终可能会遇到一些意外行为。

附带说明一下,我有一个相关的问题:上述代码的性能,因为您在每次文件请求时都会受到一些惩罚。见here。是的,您需要 4.5 完整的 .NET 配置文件。

【讨论】:

【参考方案3】:

File.OpenBinaryDirect 在您使用 Oauth accestoken 时可能会导致异常 解释于This Article

代码应该写成下面这样避免异常

 Uri filename = new Uri(filepath);
        string server = filename.AbsoluteUri.Replace(filename.AbsolutePath, 
         "");
        string serverrelative = filename.AbsolutePath;

        Microsoft.SharePoint.Client.File file = 
        this.ClientContext.Web.GetFileByServerRelativeUrl(serverrelative);
        this.ClientContext.Load(file);
        ClientResult<Stream> streamResult = file.OpenBinaryStream();
        this.ClientContext.ExecuteQuery();
        return streamResult.Value;

【讨论】:

【参考方案4】:

这个评论有点晚了,但我会在这里留下我使用 SharePoin Online 库的结果,它非常易于在您的项目中使用和实施,只需转到 .Net 的 NuGet 管理员并添加 Microsoft.SharePoint。 CSOM 到您的项目中。

[https://developer.microsoft.com/en-us/office/blogs/new-sharepoint-csom-version-released-for-office-365-may-2017/][1]

以下代码 sn-p 将帮助您将凭据连接到您的 SharePoint 网站,您还可以从特定网站和文件夹读取和下载文件。

using System;
using System.IO;
using System.Linq;
using System.Web;
using Microsoft.SharePoint.Client;
using System.Security;

using ClientOM = Microsoft.SharePoint.Client;

namespace MvcApplication.Models.Home

    public class SharepointModel
    
        public ClientContext clientContext  get; set; 
        private string ServerSiteUrl = "https://somecompany.sharepoint.com/sites/ITVillahermosa";
        private string LibraryUrl = "Shared Documents/Invoices/";
        private string UserName = "someone.surname@somecompany.com";
        private string Password = "********";
        private Web WebClient  get; set; 

        public SharepointModel()
        
            this.Connect();
        

        public void Connect()
        
            try
            
                using (clientContext = new ClientContext(ServerSiteUrl))
                
                    var securePassword = new SecureString();
                    foreach (char c in Password)
                    
                        securePassword.AppendChar(c);
                    

                    clientContext.Credentials = new SharePointOnlineCredentials(UserName, securePassword);
                    WebClient = clientContext.Web;
                
            
            catch (Exception ex)
            
                throw (ex);
            
        

        public string UploadMultiFiles(HttpRequestBase Request, HttpServerUtilityBase Server)
        
            try
            
                HttpPostedFileBase file = null;
                for (int f = 0; f < Request.Files.Count; f++)
                
                    file = Request.Files[f] as HttpPostedFileBase;

                    string[] SubFolders = LibraryUrl.Split('/');
                    string filename = System.IO.Path.GetFileName(file.FileName);
                    var path = System.IO.Path.Combine(Server.MapPath("~/App_Data/uploads"), filename);
                    file.SaveAs(path);

                    clientContext.Load(WebClient, website => website.Lists, website => website.ServerRelativeUrl);
                    clientContext.ExecuteQuery();

                    //https://somecompany.sharepoint.com/sites/ITVillahermosa/Shared Documents/
                    List documentsList = clientContext.Web.Lists.GetByTitle("Documents"); //Shared Documents -> Documents
                    clientContext.Load(documentsList, i => i.RootFolder.Folders, i => i.RootFolder);
                    clientContext.ExecuteQuery();

                    string SubFolderName = SubFolders[1];//Get SubFolder 'Invoice'
                    var folderToBindTo = documentsList.RootFolder.Folders;
                    var folderToUpload = folderToBindTo.Where(i => i.Name == SubFolderName).First();

                    var fileCreationInformation = new FileCreationInformation();
                    //Assign to content byte[] i.e. documentStream
                    fileCreationInformation.Content = System.IO.File.ReadAllBytes(path);
                    //Allow owerwrite of document
                    fileCreationInformation.Overwrite = true;
                    //Upload URL
                    fileCreationInformation.Url = ServerSiteUrl + LibraryUrl + filename;

                    Microsoft.SharePoint.Client.File uploadFile = documentsList.RootFolder.Files.Add(fileCreationInformation);

                    //Update the metadata for a field having name "DocType"
                    uploadFile.ListItemAllFields["Title"] = "UploadedCSOM";

                    uploadFile.ListItemAllFields.Update();
                    clientContext.ExecuteQuery();
                

                return "";
            
            catch (Exception ex)
            
                throw (ex);
            
        

        public string DownloadFiles()
        
            try
            
                string tempLocation = @"c:\Downloads\Sharepoint\";
                System.IO.DirectoryInfo di = new DirectoryInfo(tempLocation);
                foreach (FileInfo file in di.GetFiles())
                
                    file.Delete();
                

                FileCollection files = WebClient.GetFolderByServerRelativeUrl(this.LibraryUrl).Files;
                clientContext.Load(files);
                clientContext.ExecuteQuery();

                if (clientContext.HasPendingRequest)
                    clientContext.ExecuteQuery();

                foreach (ClientOM.File file in files)
                
                    FileInformation fileInfo = ClientOM.File.OpenBinaryDirect(clientContext, file.ServerRelativeUrl);
                    clientContext.ExecuteQuery();

                    var filePath = tempLocation + file.Name;
                    using (var fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Create))
                    
                        fileInfo.Stream.CopyTo(fileStream);
                    
                

                return "";
            
            catch (Exception ex)
            
                throw (ex);
            
        

    

然后在这种情况下从控制器调用函数 MVC ASP.NET 以下列方式完成。

using MvcApplication.Models.Home;
using System;
using System.Web.Mvc;

namespace MvcApplication.Controllers

    public class SharepointController : MvcBoostraBaseController
    
        [HttpPost]
        public ActionResult Upload(FormCollection form)
        
            try
            
                SharepointModel sharepointModel = new SharepointModel();
                return Json(sharepointModel.UploadMultiFiles(Request, Server), JsonRequestBehavior.AllowGet);
            
            catch (Exception ex)
            
                return ThrowJSONError(ex);
            
        

        public ActionResult Download(string ServerUrl, string RelativeUrl)
        
            try
            
                SharepointModel sharepointModel = new SharepointModel();
                return Json(sharepointModel.DownloadFiles(), JsonRequestBehavior.AllowGet);
            
            catch (Exception ex)
            
                return ThrowJSONError(ex);
            
        
    

如果你需要这个源代码,你可以访问我的 github 仓库

https://github.com/israelz11/MvcBoostrapTestSharePoint/

【讨论】:

【参考方案5】:
Private Sub DownloadFile(relativeUrl As String, destinationPath As String, name As String)
    Try
        destinationPath = Replace(destinationPath + "\" + name, "\\", "\")
        Dim fi As FileInformation = Microsoft.SharePoint.Client.File.OpenBinaryDirect(Me.context, relativeUrl)
        Dim down As Stream = System.IO.File.Create(destinationPath)
        Dim a As Integer = fi.Stream.ReadByte()
        While a <> -1
            down.WriteByte(CType(a, Byte))
            a = fi.Stream.ReadByte()
        End While
    Catch ex As Exception
        ToLog(Type.ERROR, ex.Message)
    End Try
End Sub

【讨论】:

【参考方案6】:

虽然这是一篇旧帖子并且有很多答案,但在这里我有我的代码版本,可以使用 CSOM(c#) 将文件上传文件到 sharepoint 2013

我希望如果您正在下载和上传文件,那么您知道如何创建Clientcontext 对象和Web 对象

/* Assuming you have created ClientContext object and Web object*/
string listTitle = "List title where you want your file to upload";
string filePath = "your file physical path";
List oList = web.Lists.GetByTitle(listTitle);
clientContext.Load(oList.RootFolder);//to load the folder where you will upload the file
FileCreationInformation fileInfo = new FileCreationInformation();

fileInfo.Overwrite = true;
fileInfo.Content = System.IO.File.ReadAllBytes(filePath);
fileInfo.Url = fileName;

File fileToUpload = fileCollection.Add(fileInfo);
clientContext.ExecuteQuery();

fileToUpload.CheckIn("your checkin comment", CheckinType.MajorCheckIn);
if (oList.EnableMinorVersions)

    fileToUpload.Publish("your publish comment");
    clientContext.ExecuteQuery();

if (oList.EnableModeration)

     fileToUpload.Approve("your approve comment"); 

clientContext.ExecuteQuery();

这里是下载代码

List oList = web.Lists.GetByTitle("ListNameWhereFileExist");
clientContext.Load(oList);
clientContext.Load(oList.RootFolder);
clientContext.Load(oList.RootFolder.Files);
clientContext.ExecuteQuery();
FileCollection fileCollection = oList.RootFolder.Files;
File SP_file = fileCollection.GetByUrl("fileNameToDownloadWithExtension");
clientContext.Load(SP_file);
clientContext.ExecuteQuery();                
var Local_stream = System.IO.File.Open("c:/testing/" + SP_file.Name, System.IO.FileMode.CreateNew);
var fileInformation = File.OpenBinaryDirect(clientContext, SP_file.ServerRelativeUrl);
var Sp_Stream = fileInformation.Stream;
Sp_Stream.CopyTo(Local_stream);

我认为仍然有不同的方式可以用于上传和下载。

【讨论】:

【参考方案7】:

只是建议 SharePoint 2013 在线和本地文件编码为 UTF-8 BOM。 确保您的文件是 UTF-8 BOM,否则您上传的 html 和脚本可能无法在浏览器中正确呈现。

【讨论】:

【参考方案8】:

我建议您阅读一些有关您可以使用 CSOM 做什么的 Microsoft 文档。这可能是您正在寻找的一个示例,但 msdn 中记录了一个庞大的 API。

// Starting with ClientContext, the constructor requires a URL to the 
// server running SharePoint. 
ClientContext context = new ClientContext("http://SiteUrl"); 

// Assume that the web has a list named "Announcements". 
List announcementsList = context.Web.Lists.GetByTitle("Announcements"); 

// Assume there is a list item with ID=1. 
ListItem listItem = announcementsList.Items.GetById(1); 

// Write a new value to the Body field of the Announcement item.
listItem["Body"] = "This is my new value!!"; 
listItem.Update(); 

context.ExecuteQuery(); 

发件人:http://msdn.microsoft.com/en-us/library/fp179912.aspx

【讨论】:

这与下载/上传文件无关。您正在使用此代码更新列表项

以上是关于如何使用 CSOM 从/向 SharePoint 2013 下载/上传文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 CSOM 禁用 SharePoint 2013 警报

csharp 使用CSOM创建Sharepoint Wiki页面

在 .Net Core 应用程序中使用 SharePoint CSOM

如何在 CSOM 请求中包含项目的 FieldValues

Sharepoint Online 使用 C# / CSOM 更改 WebPart 视图查询

将自定义 Web 部件添加到页面 SharePoint 2013 c# csom