将文件上传到与httpclient的共享点

时间:2019-07-04 08:24:44

标签: c# sharepoint

我正在尝试使用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

1 个答案:

答案 0 :(得分: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;

也可以不使用MultipartFormDataContent来尝试通过PostAsync发送ByteArray

与您的情况大致相同

    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))
    {
        ByteArrayContent content = new ByteArrayContent(new MemoryStream(System.IO.File.ReadAllBytes(filePath)).ToArray());    

        HttpResponseMessage response = await 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

UPDATE

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

,用于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。

请注意,如果您在此lib上激活了版本控制,则文件将在上传后检出,并且您需要使用其他上下文检入。ExecuteQuery()。

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

更新

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

但是我在SP2013上尝试了相同的操作,但结果并不令人满意...需要花费很多时间,我等待了很长时间(超过2个小时)才能上传0.5GB的文件,但上传仍未完成结束。

请注意,要扩展上传,您必须更改:

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

请参考linklink(并非CSOM上传当然需要全部内容)