【问题标题】:Upload file to sharepoint with httpclient使用 httpclient 将文件上传到共享点
【发布时间】:2019-11-14 22:35:11
【问题描述】:

我正在尝试使用 HttpClient 或其他方式将文件从代码上传到 sharepoint server 2013。 (我不想使用“Microsoft.SharePoint.Client”dll),因为这个 dll 对于大文件存在一些问题。

我的 HttpClient 代码如下所示:

public async Task UploadAsync(string filePath)
{
    string sharePointUrl = "http://codey-sharepoint/sites/codysite";
    string folderUrl = "/Documents";
    string fileNameNotFullPAth = System.IO.Path.GetFileName(filePath);
    var offset = 0L;
    var endpointUrl = string.Format("{0}/_api/web/getfolderbyserverrelativeurl(\'{1}\')/Files/add(url=\'{2}\',overwrite=true)", sharePointUrl, folderUrl, fileNameNotFullPAth);

      using (var handler = new HttpClientHandler { Credentials = new NetworkCredential("codey", "codey123") })
      using (var client = new HttpClient(handler))
      using (var contect=new MultipartFormDataContent("boundry ---"))
      {
         contect.Add(new StreamContent(new MemoryStream(System.IO.File.ReadAllBytes(filePath))), "file", "tst.txt");
         using (var msg = await client.PostAsync(endpointUrl,contect))
         {
             Console.WriteLine(msg.StatusCode);
             Console.WriteLine(msg.IsSuccessStatusCode);
             var input = await msg.Content.ReadAsStringAsync();
             try
             {
               XDocument doc = XDocument.Parse(input);
               Console.WriteLine(doc.ToString());
             }catch { Console.WriteLine("XML Parse error"); }
         }                
      }
}

我的输出:

Unaouthorized

False

XML Parse error

现在我只想上传简单的小文件,不使用外部DLL

【问题讨论】:

    标签: c# sharepoint


    【解决方案1】:

    可能需要 HttpClient 对象中的一些附加标头。尝试添加这个:

    
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.Add("Accept", "application/json;odata=nometadata");
        client.DefaultRequestHeaders.Add("binaryStringRequestBody", "true");
        client.DefaultRequestHeaders.Add("X-RequestDigest", tFormDigest.Result.FormDigestValue);
        client.MaxResponseContentBufferSize = 2147483647;
    

    您也可以尝试使用 PostAsync 发送 ByteArray 而不是使用 MultipartFormDataContent

    你的情况或多或少是这样的

    var endpointUrl = string.Format("{0}/_api/web/getfolderbyserverrelativeurl(\'{1}\')/Files/add(url=\'{2}\',overwrite=true)", sharePointUrl, folderUrl , 文件名非全路径); 使用 (var handler = new HttpClientHandler { Credentials = new NetworkCredential("codey", "codey123") }) 使用 (var client = new HttpClient(handler)) { ByteArrayContent 内容 = new ByteArrayContent(new MemoryStream(System.IO.File.ReadAllBytes(filePath)).ToArray()); HttpResponseMessage 响应 = 等待 client.PostAsync(endpointUrl, content).ConfigureAwait(false); }

    另外...您是否考虑过使用 CSOM?也许这会是更好的方法,因为您已经在使用 C#。

    对于本地部署(2013 .. 但也适用于所有版本)你有

    https://www.nuget.org/packages/Microsoft.SharePoint2013.CSOM/

    在线

    https://www.nuget.org/packages/Microsoft.SharePointOnline.CSOM

    更新

    我将此 nuget 添加到一些简单的 c# 控制台应用程序中(与链接中的相同)

    用于 2MB 以下小文件的首选代码是

    
    
        class Program
            {
                static void Main(string[] args)
                {
                    try
                    {
                        Console.WriteLine("start");
                        byte[] b = System.IO.File.ReadAllBytes(@"[PATH TO FILE LIKE C:\test.png]");
                        using (ClientContext context = new ClientContext("[SITECOLLECTION URL]"))
                        {
                            List list = context.Web.Lists.GetByTitle("[LIB NAME LIKE 'DOCUMENTS']");
                            FileCreationInformation fileInfo = new FileCreationInformation();
                            fileInfo.Content = b;
                            fileInfo.Overwrite = true;
    
                            fileInfo.Url = "[SITECOLLECTION URL]" + "/[LIB NAME FROM URL LIKE 'DOCUMENTS']/" + "[FILE NAME LIKE 'test.png']";
                            Microsoft.SharePoint.Client.File uploadFile = list.RootFolder.Files.Add(fileInfo);
    
                            uploadFile.ListItemAllFields.Update();
                            context.ExecuteQuery();
                        }
                        Console.WriteLine("end");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("error -> " +  ex.Message);
                    }
                    finally
                    {
                        Console.ReadLine();
                    }
                }
            }
    
    

    2GB 以下的较大文件(对于 SP2013)的代码是(我测试了一个大约 100MB 的文件)

    
    
        class Program
            {
                static void Main(string[] args)
                {
                    try
                    {
                        Console.WriteLine("start");
                        using (ClientContext context = new ClientContext("[SITECOLLECTION URL]"))
                        {
                            using (FileStream fs = new FileStream(@"[PATH TO FILE LIKE C:\test.png]", FileMode.Open))
                            {
                                Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, "/[LIB NAME FROM URL LIKE 'DOCUMENTS']/" + "[FILE NAME LIKE 'test.png']", fs, true);
                            }
                        }
                        Console.WriteLine("end");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("error -> " +  ex.Message);
                    }
                    finally
                    {
                        Console.ReadLine();
                    }
                }
            }
    
    

    请注意,我刚刚对其进行了测试,但在 SP2016 上一切正常(但 nuget 适用于 SP2013 并且工作正常),我目前无法访问任何 SP2013 进行检查。

    请注意,如果您在此库上激活了版本控制,则文件将在上传后检出,您需要使用另一个 context.ExecuteQuery() 检入。

    请注意,如果您想以不同的用户身份运行此代码(现在它将与当前登录的帐户相同),您需要定义 networkCredentials 提供登录名、密码和域。

    更新

    请查看此方法在 SP2016 上传 470MB 文件(3 分钟)上的结果

    但是我在 SP2013 上尝试了同样的方法,结果并不令人满意......这需要很长时间,我等了很长时间(超过 2 小时)才上传 0.5GB 文件,但上传仍然没有完成结束。

    请注意,要延长上传时间,您必须进行更改:

    1. 在 CA 中上传文件大小
    2. 添加上下文。RequestTimeout = -1;到 CSOM 代码
    3. 在 IIS 上设置更大的超时会话时间

    请参考linklink(当然不是所有的CSOM上传都需要)

    【讨论】:

    • 2013 年的好链接,你知道我在哪里可以找到文档吗? 2013 年,我正在尝试上传大文件 ~2GB...
    • 不幸的是,在 SP2013 中,2GB 是软件边界。默认情况下,它与 SP2010 中一样为 250 MB,但由于它是阈值限制,您可以更改它,但限制不能大于 2GB,这是一个边界(无法更改)。请参考:docs.microsoft.com/pl-pl/SharePoint/install/…,这里是如何更改:blogs.technet.microsoft.com/sammykailini/2013/11/06/… 如果我记得很清楚,SP2016 的限制是 10GB,SP2019 的限制是 15GB。可以考虑升级SP版本吗?
    • 你知道如何使用this dll 从代码上传 1 GB 吗?我手动上传1GB成功但不是通过代码,我试过UploadFileSlicePerSlice,但是dll中没有“StartUpload”这样的方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 2022-01-18
    相关资源
    最近更新 更多