Загрузка файла из команд MS программно - PullRequest
0 голосов
/ 01 июля 2019

Ранее я разработал приложение, которое загрузило файл с корпоративного сайта Sharepoint, а затем выполнило некоторые действия с ним.

Возможности, которые были с тех пор перенесены в MS Teams, и я пытаюсь обновить приложение, чтобы использовать новую платформу. Однако у меня возникают всевозможные проблемы с загрузкой файла.

Мой старый (работает для Sharepoint) код использует WebClient для извлечения файла на основе учетных данных, ранее предоставленных пользователем:

    private string GetSchedule(string username, string password, string domain)
    {

        string tempPath = Path.GetTempFileName().Replace(".tmp", ".xlsm");
        using (WebClient client = new WebClient())
        {
            client.Credentials = new NetworkCredential(username, password, domain);
            try
            {
                client.DownloadFile(_networkSchedulePath, tempPath);
            }
            catch (WebException e)
            {
                if (e.Message.Contains("401"))
                {
                    StatusUpdated?.Invoke(this, new EventArgs<string>("Invalid Credentials Provided"));
                    Finished?.Invoke(this, null);
                    return null;
                }
                if (e.Message.Contains("404"))
                {
                    StatusUpdated?.Invoke(this, new EventArgs<string>("File Not Found"));
                    Finished?.Invoke(this, null);
                    return null;
                }
                else
                {
                    StatusUpdated?.Invoke(this, new EventArgs<string>(e.Message));
                    Finished?.Invoke(this, null);
                    return null;
                }
            }
        }
        return tempPath;
    }

Однако, когда я использую это с новой ссылкой команды, я получаю ошибку 403 Forbidden. Так есть ли способ программно получить файл из MS Teams?

Ответы [ 2 ]

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

Я ошибся в комментариях. Простая замена NetworkCredentials на SharePointOnlineCredentials не является решением.

Я не уверен, является ли следующий подход "правильным", но он работает и выглядит довольно солидно. Пожалуйста, попробуйте:

private static string GetFile(string path, string username, string password, string domain)
{
    var secureString = new SecureString();
    foreach (var ch in password)
    {
        secureString.AppendChar(ch);
    }

    string tempPath = Path.GetTempFileName().Replace(".tmp", ".xlsm");
    using (WebClient client = new WebClient())
    {
        var credentials = new SharePointOnlineCredentials(username, secureString);

        client.Headers[HttpRequestHeader.Cookie] = credentials.GetAuthenticationCookie(new Uri(path));
        try
        {
            client.DownloadFile(path, tempPath);
        }
        catch (WebException e)
        {
            // Error Handling
        }
    }
    return tempPath;
}

Другой вариант - использовать CSOM, а не напрямую использовать веб-клиента. Нет, я столкнулся с ошибками при вызове OpenBinaryDirect() при использовании пакета NuGet Microsoft.SharePoint.Client, и похоже, что этот пакет сильно устарел. Похоже, что сейчас используется Microsoft.SharePointOnline.CSOM или Microsoft.SharePoint2019.CSOM:

private static string GetFileWithClientContext(string path, string username, string password, string domain)
{
    var secureString = new SecureString();
    foreach (var ch in password)
    {
        secureString.AppendChar(ch);
    }
    string tempPath = Path.GetTempFileName().Replace(".tmp", Path.GetExtension(path));
    using (var context = new ClientContext(path))
    {
        context.Credentials = new SharePointOnlineCredentials(username, secureString);

        try
        {
            using (var file = Microsoft.SharePoint.Client.File.OpenBinaryDirect(context, new Uri(path).AbsolutePath))
            using (var outFile = System.IO.File.OpenWrite(tempPath))
            {
                file.Stream.CopyTo(outFile);
            }
        }
        catch (WebException e)
        {
            // Error Handling
        }
    }
    return tempPath;
}
0 голосов
/ 10 июля 2019

Спасибо JLRishe за помощь, его ответ и предоставленные комментарии.Однако окончательное решение отличалось от того, которое было в его ответе, поэтому я публикую его здесь:


Для этого широко используется пакет OfficeDevPnP.Core.

Во-первыхAuthenticationManager используется для получения ClientContext с точки зрения конкретного сайта sharepoint, к которому необходимо получить доступ.Это выскакивает окно, чтобы учесть МФА.Затем различные компоненты загружаются через объект ClientContext.Отсюда файл выбирается через Guid и выводится на диск.

private string GetSchedule()
{
    string tempPath = Path.GetTempFileName().Replace(".tmp", ".xlsm");
    try
    {
        AuthenticationManager authManager = new OfficeDevPnP.Core.AuthenticationManager();
        ClientContext ctx = authManager.GetWebLoginClientContext("https://oursite.sharepoint.com/sites/ourspecificsite/");
        Web web = ctx.Web;
        Microsoft.SharePoint.Client.File schedule = web.GetFileById(new Guid("ourguid"));
        ctx.Load(web);
        ctx.Load(schedule);
        ctx.ExecuteQuery();
        FileInformation fInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(ctx, schedule.ServerRelativeUrl);
        using (var fileStream = File.Create(tempPath))
        {
            fInfo.Stream.CopyTo(fileStream);
        }
    }
    catch (WebException e)
    {
        StatusUpdated?.Invoke(this, new EventArgs<string>(e.Message));
        return null;
    }

    return tempPath;
}
...