Загрузить файл в sharepoint с помощью httpclient - PullRequest
0 голосов
/ 04 июля 2019

Я пытаюсь загрузить файл на сервер sharepoint 2013 из кода с помощью HttpClient или другим способом. ( Я не хочу использовать dll "Microsoft.SharePoint.Client"), потому что есть некоторые проблемы с этой 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 Ответ

1 голос
/ 05 июля 2019

возможно, требуются дополнительные заголовки в объекте HttpClient. Попробуйте возможно добавить это:

<code>
    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 вы можете попробовать отправить ByteArray с PostAsync

Что-то более или менее подобное для вашего дела

    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 #.

для on-prem (2013 .. но есть и для всех версий) У вас есть

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

и для онлайн

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

UPDATE

Я добавил этот nuget в простое консольное приложение на c # (так же, как по ссылке) enter image description here

и предпочтительный код, используемый для небольших файлов размером менее 2 МБ, -



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

код для более крупных файлов до 2 ГБ (для SP2013): (я проверял файл, который занимал около 100 МБ)



    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, указав логин, пароль и домен.

UPDATE

см. Результат этого метода на SP2016 при загрузке файла размером 470 МБ (3 минуты) enter image description here

НО я попробовал то же самое на SP2013, и результат был неудовлетворительным ... это заняло много времени, и я очень долго (более 2 часов) ждал загрузки файла размером 0,5 ГБ, а загрузка все еще не завершилась в конец.

Пожалуйста, имейте в виду, чтобы продлить загрузку Вы должны изменить:

  1. размер загружаемого файла в CA
  2. добавить context.RequestTimeout = -1; в код CSOM
  3. установить большее время ожидания сеанса на IIS

пожалуйста, обратитесь к ссылке и ссылке (не все, конечно, необходимо для загрузки CSOM)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...